<template>
  <!-- AI生成器覆盖层 - 移除@click.self="close"以防止点击外部关闭 -->
  <div class="ai-generator-overlay">
    <!-- 生成器容器 -->
    <div class="ai-generator-container" :class="{ 'fullscreen': isFullscreen }">
      <!-- 头部区域 -->
      <div class="ai-generator-header">
        <div class="header-left">
          <h2><i class="fas fa-robot"></i> AI智能题目生成器</h2>
          <div class="ai-status" v-if="generating">
            <div class="pulse-dot"></div>
            <span>{{ thinkingText }}</span>
          </div>
        </div>
        <div class="header-actions">
          <button class="btn-icon" @click="toggleFullscreen" :title="isFullscreen ? '退出全屏' : '全屏模式'">
            <i :class="isFullscreen ? 'fas fa-compress' : 'fas fa-expand'"></i>
          </button>
          <button class="btn-icon btn-close" @click="close" title="关闭">
            <i class="fas fa-times"></i>
          </button>
        </div>
      </div>

      <!-- 内容区域 -->
      <div class="ai-generator-content">
        <!-- 左侧面板 - 题库信息和生成配置 -->
        <div class="left-panel">
          <!-- 题库信息卡片 -->
          <GenerateBankCard
            :bank="bank"
            :questions="question"
            :is-analyzing.sync="isAnalyzing"
            :ai-analysis-result="aiAnalysisResult"
            :suggested-keywords="suggestedKeywords"
            :recommendation-options="recommendationOptions"
            @analyze-bank="analyzeBank"
            @apply-recommendation="applyRecommendation"
            @start-generate="handleStartGenerate"
            @analysis-completed="handleAnalysisCompleted"
          />
          <!-- 生成配置区域 -->
          <div class="config-section">
            <div class="section-header">
              <i class="fas fa-cog"></i>
              <h3>智能生成配置</h3>
              <div class="ai-tag">
                <i class="fas fa-bolt"></i> AI优化
              </div>
            </div>

            <!-- 关键词输入 -->
            <div class="config-group">
              <label>主题关键词 <span class="ai-suggestion-badge" v-if="suggestedKeywords.length > 0">AI推荐</span></label>
              <div class="keyword-input-container">
                <div class="input-with-icon">
                  <i class="fas fa-tags"></i>
                  <input
                      v-model="config.keywords"
                      type="text"
                      placeholder="例如: Java多线程,数据库索引,Spring框架（多个关键词可用中文，或英文,隔开）"
                      class="modern-input"
                      @input="analyzeKeywords">
                  <button class="btn-smart-suggest" @click="showSmartSuggestions" title="自动添加智能关键词">
                    <i class="fas fa-lightbulb"></i>
                  </button>
                </div>
                <!-- 添加关键词标签显示区域 -->
                <div class="keyword-tags" v-if="keywordTags.length > 0">
                  <transition-group name="tag-fade">
                    <span v-for="(tag, index) in keywordTags" 
                          :key="tag" 
                          class="keyword-tag"
                          @click="removeKeyword(index)">
                      {{ tag }}
                      <i class="fas fa-times"></i>
                    </span>
                  </transition-group>
                </div>
                <div class="ai-feedback" v-if="keywordFeedback">
                  <i class="fas" :class="keywordFeedbackIcon"></i> <span v-html="keywordFeedback"></span>
                </div>
              </div>

              <!-- AI建议关键词 -->
              <div class="ai-suggestions" v-if="suggestedKeywords.length > 0">
                <div class="suggestion-header">
                  <i class="fas fa-bolt"></i>
                  <span>AI建议关键词</span>
                  <button class="btn-refresh" @click="refreshSuggestions" :class="{ 'refreshing': isRefreshingSuggestions }" :disabled="isRefreshingSuggestions">
                    <i class="fas fa-sync-alt"></i>
                  </button>
                </div>
                <transition-group 
                  name="suggestions-refresh" 
                  tag="div" 
                  class="suggestion-tags"
                  :class="{'is-refreshing': isRefreshingSuggestions}"
                >
                  <span
                      v-for="(keyword, index) in suggestedKeywords"
                      :key="keyword + '-' + index"
                      class="tag"
                      :class="{'refreshing': isRefreshingSuggestions}"
                      @click="applyKeyword(keyword)">
                    {{ keyword }}
                    <i class="fas" :class="isRefreshingSuggestions ? 'fa-spinner fa-spin' : 'fa-plus'"></i>
                  </span>
                </transition-group>
              </div>
            </div>

            <!-- 生成参数 -->
            <div class="config-grid">
              <div class="config-item">
                <label>题目数量</label>
                <div class="input-with-icon">
                  <i class="fas fa-hashtag"></i>
                  <input
                      :value="totalQuestions"
                      type="number" min="1" max="50"
                      class="modern-input"
                      readonly>
                </div>
              </div>

              <div class="config-item">
                <label>难度级别</label>
                <div class="input-with-icon">
                  <i class="fas fa-signal"></i>
                  <select v-model="config.difficulty" class="modern-input">
                    <option v-for="(label, value) in difficultyOptions"
                            :value="value" :key="value">
                      {{ label }}
                    </option>
                  </select>
                </div>
              </div>

              <div class="config-item">
                <label>生成风格</label>
                <div class="input-with-icon">
                  <i class="fas fa-paint-brush"></i>
                  <select v-model="config.style" class="modern-input">
                    <option v-for="(label, value) in styleOptions"
                            :value="value" :key="value">
                      {{ label }}
                    </option>
                  </select>
                </div>
              </div>
            </div>

            <!-- 题型配置 -->
            <div class="type-config-section">
              <div class="section-header">
                <i class="fas fa-list-alt"></i>
                <h3>题型配置</h3>
                <div class="total-count">
                  总计: <span class="highlight">{{ totalQuestions }}</span> / <span class="max-count">30</span> 题
                </div>
              </div>

              <div class="type-config-grid">
                <div v-for="type in questionTypes" :key="type.value"
                     class="type-config-card"
                     :class="{ 'active': isTypeSelected(type.value) }"
                     @click="toggleQuestionType(type.value)">
                  <div class="type-icon" :style="{ backgroundColor: typeColors[type.value] }">
                    <i :class="type.icon"></i>
                  </div>
                  <div class="type-info">
                    <span class="type-name">{{ type.label }}</span>
                    <span class="type-desc">{{ getTypeDescription(type.value) }}</span>
                  </div>
                  <div class="type-count" v-if="isTypeSelected(type.value)">
                    <button class="count-btn" @click.stop="decrementType(type.value)">
                      <i class="fas fa-minus"></i>
                    </button>
                    <span class="count-value">{{ config.questionTypes[type.value] }}</span>
                    <button class="count-btn" @click.stop="incrementType(type.value)">
                      <i class="fas fa-plus"></i>
                    </button>
                  </div>
                </div>
              </div>
            </div>

            <!-- 智能推荐配置 -->
            <div class="ai-recommendations">
              <div class="section-header">
                <i class="fas fa-magic"></i>
                <h3>智能推荐方案</h3>
                <div class="header-actions">
                  <button class="btn-refresh-recommendations" @click="refreshRecommendationsOnly" :disabled="isAnalyzingRecommendations">
                    <i class="fas fa-sync-alt"></i> 刷新方案
                  </button>
                </div>
              </div>
              <!-- 新增分析中动画 -->
              <div class="analyzing-recommendations" v-if="isAnalyzingRecommendations">
                <div class="ai-loading-animation">
                  <div class="ai-brain">
                    <div class="brain-lobe left"></div>
                    <div class="brain-lobe right"></div>
                    <div class="brain-center"></div>
                  </div>
                  <div class="neural-connections">
                    <div class="connection" v-for="i in 8" :key="i" :style="{
                      '--delay': `${i * 0.1}s`,
                      '--duration': `${0.5 + Math.random() * 0.5}s`
                    }"></div>
                  </div>
                  <div class="loading-text">
                    <span class="text">生成推荐方案中</span>
                    <span class="dots">
                      <span class="dot" v-for="i in 3" :key="i" :style="{
                        '--delay': `${i * 0.2}s`
                      }"></span>
                    </span>
                  </div>
                </div>
              </div>
              <div class="recommendation-options" v-else>
                <div
                    v-for="(option, index) in recommendationOptions"
                    :key="index"
                    class="recommendation-card"
                    :class="{ active: isRecommendationSelected(option) }"
                    @click="toggleRecommendation(option)">
                  <div class="recommendation-icon" :style="{ backgroundColor: typeColors[Object.keys(option.types)[index]] }">
                    <i class="fas fa-lightbulb"></i>
                  </div>
                  <div class="recommendation-content">
                    <h4>{{ option.label }}</h4>
                    <div class="recommendation-stats">
                      <span class="stat-item">
                        <i class="fas fa-signal"></i> {{ difficultyOptions[option.difficulty] }}
                      </span>
                      <span class="stat-item">
                        <i class="fas fa-paint-brush"></i> {{ styleOptions[option.style] }}
                      </span>
                    </div>
                    <div class="type-tags">
                      <span v-for="(count, type) in option.types" :key="type" class="type-tag">
                        {{ getTypeName(type) }} ×{{ count }}
                      </span>
                    </div>
                  </div>
                </div>
              </div>
              <!-- 空状态提示 - 当没有推荐且不在分析中时显示 -->
              <div class="empty-recommendations" v-if="recommendationOptions.length === 0 && !isAnalyzingRecommendations">
                <i class="fas fa-lightbulb"></i>
                <p>暂无智能推荐方案，请点击"题库分析"生成</p>
              </div>
            </div>
          </div>
        </div>

        <!-- 右侧面板 - 生成结果 -->
        <div class="result-panel">
          <div class="result-header">
            <h3><i class="fas fa-magic"></i> 生成结果</h3>
            <div class="result-stats">
              <div class="stat-item" v-for="type in selectedTypes" :key="type">
                <span class="stat-badge" :style="{ backgroundColor: typeColors[type] }">
                  {{ getTypeName(type) }}
                </span>
                <span class="stat-count">{{ getPreviewCount(type) }}/{{ config.questionTypes[type] }}</span>
              </div>
              <div class="quota-indicator" :class="{'quota-warning': totalQuestions >= 30}">
                <i class="fas" :class="totalQuestions >= 30 ? 'fa-exclamation-circle' : 'fa-info-circle'"></i>
                {{ totalQuestions }}/30 题
              </div>
              <div class="ai-actions">
                <button class="btn-ai-optimize" @click="optimizeQuestions">
                  <i class="fas fa-wand-magic-sparkles"></i> AI优化
                </button>
                <button class="btn-ai-optimize" v-if="previewQuestions.length > 0" @click="exportQuestions">
                  <i class="fas fa-file-export"></i> 导出题目
                </button>
              </div>
            </div>
          </div>

          <div class="result-content">
            <div v-if="generating" class="generating-state">
              <div class="ai-thinking-animation">
                <div class="ai-avatar">
                  <i class="fas fa-robot"></i>
                </div>
                <div class="thinking-bubbles">
                  <div class="bubble" v-for="(text, index) in thinkingTexts"
                       :key="index"
                       :class="{ 'active': thinkingText === text }">
                    {{ text }}
                  </div>
                </div>
              </div>

              <div class="progress-container">
                <div class="progress-info">
                  <span>生成进度</span>
                  <span>{{ progress }}%</span>
                </div>
                <div class="progress-bar">
                  <div class="progress-fill" :style="{ width: `${progress}%` }"></div>
                </div>
              </div>

              <!-- 生成预览 -->
              <div class="generation-preview" v-if="previewQuestions.length > 0">
                <h5>已生成题目预览</h5>
                <div class="preview-scroll">
                  <div
                      v-for="(q, idx) in previewQuestions.slice(0, 3)"
                      :key="'preview-'+idx"
                      class="preview-item">
                    <span class="preview-type" :style="{ backgroundColor: q.typeColor }">
                      {{ q.typeLabel }}
                    </span>
                    <span class="preview-content">{{ q.content }}</span>
                  </div>
                </div>
              </div>
            </div>

            <div v-if="error" class="error-message">
              <i class="fas fa-exclamation-triangle"></i>
              {{ error }}
              <button class="retry-btn" @click="startGeneration">
                <i class="fas fa-sync-alt"></i> 重试
              </button>
            </div>

            <div v-if="previewQuestions.length > 0" class="questions-preview">
              <div v-for="(q, idx) in previewQuestions"
                   :key="'preview-'+idx"
                   class="question-card"
                   :class="[q.type, {'regenerating': regeneratingIndex === idx}]">
                <div class="question-header">
                  <span class="question-index">{{ idx + 1 }}.</span>
                  <span class="question-type" :style="{ backgroundColor: getQuestionTypeColor(q) }">
                    <i :class="{
                      'fas fa-dot-circle': q.typeLabel==='单选',
                      'fas fa-check-double': q.typeLabel==='多选',
                      'fas fa-balance-scale': q.typeLabel==='判断',
                      'fas fa-pencil-alt': q.typeLabel==='填空',
                      'fas fa-align-left': q.typeLabel==='简答'
                    }"></i>
                    {{ q.typeLabel || getTypeNameByNum(q.typeNum) }}
                  </span>
                  <span class="question-difficulty" :style="{ backgroundColor: q.difficultyColor, color: 'white' }">
                    {{ q.difficultyLabel }}
                  </span>
                  <div class="question-actions">
                    <button class="btn-action btn-accept" @click="acceptQuestion(q)" :disabled="regeneratingIndex === idx">
                      <i class="fas fa-check"></i> 采用
                    </button>
                    <button class="btn-action btn-reject" @click="rejectQuestion(idx)" :disabled="regeneratingIndex === idx">
                      <i class="fas fa-times"></i> 拒绝
                    </button>
                    <button class="btn-action btn-regenerate" @click="regenerateQuestion(idx)" :disabled="regeneratingIndex === idx" :class="{'loading': regeneratingIndex === idx}">
                      <i class="fas" :class="regeneratingIndex === idx ? 'fa-spinner fa-spin' : 'fa-sync-alt'"></i> {{ regeneratingIndex === idx ? '生成中...' : '重生成' }}
                    </button>
                  </div>
                </div>
                <div class="question-content">
                  {{ q.content }}
                </div>
                
                <!-- 重新生成中的覆盖层 -->
                <div v-if="regeneratingIndex === idx" class="regenerating-overlay">
                  <div class="regenerating-spinner">
                    <div class="spinner-border text-primary"></div>
                    <div class="regenerating-text">正在重新生成中...</div>
                  </div>
                </div>
                
                <div class="question-options" v-if="q.optionsKV && q.optionsKV.length">
                  <div v-for="(option, optIdx) in q.optionsKV"
                       :key="optIdx"
                       class="option-item"
                       :class="{ 'correct': isCorrectOption(q, option.key) }">
                    <span class="option-letter">{{ option.key }}.</span>
                    <span class="option-text">{{ option.value }}</span>
                    <span v-if="isCorrectOption(q, option.key)" class="correct-mark-after">
                      <i class="fas fa-check-circle"></i> 正确答案
                    </span>
                  </div>
                </div>
                <div class="question-footer">
                  <!-- 正确答案部分（简答题不显示） -->
                  <div class="answer-section" v-if="q.correct_answer && q.typeLabel !== '简答'">
                    <span class="answer-label">正确答案:</span>
                    <span class="answer-value">{{ formatAnswer(q) }}</span>
                  </div>

                  <!-- 答案解析部分（所有题目都显示） -->
                  <div class="analysis-section">
                    <span class="analysis-label">答案解析</span>
                    <span class="analysis-content">{{ q.parse }}</span>
                  </div>

                  <div class="ai-tag">
                    <i class="fas fa-robot"></i> AI生成
                  </div>
                </div>
              </div>

    
            </div>

            <div v-if="!generating && previewQuestions.length === 0" class="empty-state">
              <div class="empty-illustration">
                <i class="fas fa-lightbulb"></i>
              </div>
              <h4>等待生成题目</h4>
              <p>配置好生成选项后，点击"开始生成"按钮</p>
              <button class="btn-tutorial" @click="showTutorial">
                <i class="fas fa-question-circle"></i> 如何使用AI生成器
              </button>
            </div>
          </div>
        </div>
      </div>

      <!-- 底部操作按钮 -->
      <div class="ai-generator-footer">
        <div class="generation-hint" v-if="generationCompleted && previewQuestions.length > 0">
          <i class="fas fa-info-circle"></i> 请先处理完当前题目（全部采用或全部弃用）再继续生成
        </div>
        <button class="btn-generate"
                @click="startGeneration"
                :disabled="generating || !canGenerate || generationCompleted">
          <i class="fas fa-bolt"></i> {{ generating ? '生成中...' : '开始生成' }}
        </button>
        <button class="btn-save"
                v-if="previewQuestions.length > 0 && !generating"
                @click="acceptAllQuestions">
          <i class="fas fa-check-double"></i> 全部采用
        </button>
        <button class="btn-reject"
                v-if="previewQuestions.length > 0 && !generating"
                @click="rejectAllQuestions">
          <i class="fas fa-trash-alt"></i> 全部弃用 
        </button>
        <button class="btn-cancel" @click="close">
          <i class="fas fa-times-circle"></i> 取消/关闭
        </button>
      </div>
    </div>
  </div>
</template>

<script>
/**
 * AI题库生成器组件 - 用于根据题库内容和配置生成AI题目
 * 支持多种题型、难度级别和题目风格的定制化生成
 */

// 全局缓存对象，服务运行期间有效
if (!window.__AI_BANK_ANALYSIS_CACHE__) {
  window.__AI_BANK_ANALYSIS_CACHE__ = {};
}

// 引入AI生成函数
import callSiliconAI from '@/api/generate';
import { addQuestion } from '@/api/question';
import { refreshRecommendations } from '@/api/generate';

// 引入题库卡片组件
import GenerateBankCard from "@/components/questionbank/GenerateBankCard.vue";

// 系统级提示词
const systemPrompt = `你是一个智能题库分析和生成助手，负责根据题库内容和用户配置，返回结构化的分析、建议关键词和推荐方案，所有输出必须严格遵循JSON格式，不要出现任何解释性文字。`;

export default {
  name: 'AIGeneratorAddQuestion',
  props: {
    /**
     * 当前操作的题库对象
     * @property {string} bankId - 题库ID
     * @property {string} name - 题库名称
     * @property {number} avgDiffculty - 题库平均难度
     */
    bank: {
      type: Object,
      required: true
    },
    question: {
      // 数组
      type: Array,
      required: true
    }
  },
  data() {
    return {
      // ai 分析题库中
      isAnalyzing: false,
      // 新增：分析推荐方案中状态
      isAnalyzingRecommendations: false,
      // 新增：关键词刷新状态
      isRefreshingSuggestions: false,
      // 新增：记录正在重新生成的题目索引
      regeneratingIndex: -1,

      isFullscreen: false, // 是否全屏显示生成器
      generating: false, // 是否正在生成题目
      progress: 0, // 生成进度百分比
      thinkingText: '正在分析知识要点...', // 思考过程中的提示文本
      thinkingTexts: [
        '正在分析知识要点...',
        '正在构建题目结构...',
        '正在验证答案准确性...',
        '正在优化题目表述...',
        '正在进行最终检查...'
      ], // 思考过程中的提示文本列表
      thinkingInterval: null, // 思考文本切换定时器
      error: null, // 生成过程中的错误信息
      previewQuestions: [], // 预览的生成题目列表
      knowledgeGap: false, // 是否检测到知识缺口
      difficultyOptions: {
        easy: '简单',
        medium: '中等',
        hard: '困难',
      }, // 难度级别选项映射
      styleOptions: {
        exam: '考试风格',
        practice: '练习风格',
        conceptual: '概念理解',
        application: '应用实践',
        creative: '创新思维'
      }, // 题目风格选项映射
      questionTypes: [
        { value: 'single', label: '单选题', icon: 'fas fa-dot-circle' },
        { value: 'multiple', label: '多选题', icon: 'fas fa-check-double' },
        { value: 'truefalse', label: '判断题', icon: 'fas fa-balance-scale' },
        { value: 'fillblank', label: '填空题', icon: 'fas fa-pencil-alt' },
        { value: 'short_answer', label: '简答题', icon: 'fas fa-align-left' }
      ], // 支持的题目类型列表
      typeColors: {
        single: '#4361EE',
        multiple: '#3A0CA3',
        truefalse: '#10B981',
        fillblank: '#F59E0B',
        short_answer: '#8B5CF6'
      }, 
      // 题目类型对应的颜色
      difficultyColors: {
        easy: '#10B981',
        medium: '#F59E0B',
        hard: '#EF4444',
        expert: '#8B5CF6'
      }, 
      // 难度级别对应的颜色
      config: {
        difficulty: 'medium', // 默认难度级别
        count: 5, // 生成题目数量
        keywords: '', // 生成题目的关键词
        style: 'exam', // 默认题目风格
        questionTypes: {
          single: 0,
          multiple: 0,
          truefalse: 0,
          fillblank: 0,
          short_answer: 0
        }
      }, // 题目生成配置
      isGenerating: false, // 是否正在生成题目的标志
      generationCompleted: false, // 新增：标记生成已完成但题目未处理
      suggestedKeywords: [], // AI建议的关键词列表
      keywordFeedback: '', // 关键词分析反馈信息
      keywordFeedbackIcon: 'fa-lightbulb', // 关键词反馈图标
      recommendationOptions: [], // Empty initially - will show empty state

      // 最终AI分析结果
      aiAnalysisResult: {},
      // 新增缓存key
      analysisCacheKey: '',
      keywordTags: [], // 新增：存储关键词标签
      selectedRecommendations: [], // 新增：多选推荐配置
      // Ai 生成的题目
      aiQuestion: [
        {
          content: "", //  题目内容
          type: 0, // 题目类型 0 单选题，1 选择题，2 填空题 3 判断题 4 简答题
          difficulty: 0, // 难度等级 三个等级 简单（1 - 3） 中等（4 - 7） 困难 （8 - 10）， 需要使用数字
          options: "", // 选项，多选题使用数组，单选题使用字符串，判断题使用字符串，填空题和简答题没有选项
          parse: "", // 答案解析
          answer: "", // 正确答案 显示正确的选项，多个正确答案逗号隔开
        }
      ]
    }
  },
  components: {
    GenerateBankCard
  },
  computed: {
    /**
     * 获取题库平均难度信息
     * @returns {Object} - 包含难度文本和颜色的对象
     */
    difficultyInfo() {
      const level = this.bank.avgDiffculty || 0;
      const levels = {
        1: { text: '非常简单', color: '#10B981' },
        2: { text: '非常简单', color: '#10B981' },
        3: { text: '简单', color: '#10B981' },
        4: { text: '简单', color: '#10B981' },
        5: { text: '中等', color: '#F59E0B' },
        6: { text: '中等', color: '#F59E0B' },
        7: { text: '较难', color: '#EF4444' },
        8: { text: '困难', color: '#EF4444' },
        9: { text: '非常困难', color: '#EF4444' },
        10: { text: '专家级', color: '#EF4444' }
      };
      return levels[level] || { text: '未设置', color: '#94A3B8' };
    },

    /**
     * 获取已选择的题目类型列表
     * @returns {Array<string>} - 已选择的题目类型数组
     */
    selectedTypes() {
      return Object.keys(this.config.questionTypes).filter(
          type => this.config.questionTypes[type] > 0
      );
    },

    /**
     * 判断是否可以开始生成题目
     * @returns {boolean} - 可生成标志
     */
    canGenerate() {
      return (
          this.config.keywords.trim().length > 0 &&
          this.totalQuestions > 0 &&
          this.totalQuestions <= 30
      );
    },

    /**
     * 计算总共要生成的题目数量
     * @returns {number} - 题目总数
     */
    totalQuestions() {
      return Object.values(this.config.questionTypes).reduce((a, b) => a + b, 0);
    }
  },

  created() {
    // 组件创建时，生成分析缓存键名
    this.analysisCacheKey = this.bank.bankId || (this.bank.id || this.bank._id || this.bank.name);
    
    // 创建一个标记，用于判断是否是首次打开
    if (!window.__AI_BANK_FIRST_LOAD__) {
      window.__AI_BANK_FIRST_LOAD__ = {};
    }
  },
  
  mounted() {
    // 在组件挂载后，检查是否是首次加载此题库
    const firstLoadKey = this.analysisCacheKey;
    
    if (!window.__AI_BANK_FIRST_LOAD__[firstLoadKey]) {
      // 标记为已加载
      window.__AI_BANK_FIRST_LOAD__[firstLoadKey] = true;
      
      // 如果是首次加载，自动分析题库
      this.isAnalyzing = true;
      this.$nextTick(() => {
        // 直接调用子组件的analyzeBank方法
        const bankCardComponent = this.$children.find(child => child.$options.name === 'GenerateBankCard');
        if (bankCardComponent) {
          bankCardComponent.analyzeBank();
        } else {
          // 如果找不到子组件，回退到自己的分析方法
          this.analyzeBank(true);
        }
      });
    } else {
      // 非首次加载，只尝试从缓存加载
      this.tryLoadAnalysisFromCache();
    }
  },

  watch: {
    'config.keywords': {
      handler(newVal) {
        this.keywordTags = newVal.split(',')
          .map(k => k.trim())
          .filter(k => k);
      },
      immediate: true
    }
  },

  methods: {
    /**
     * 切换全屏/非全屏模式
     */
    toggleFullscreen() {
      this.isFullscreen = !this.isFullscreen;
    },

    /**
     * 关闭组件，触发关闭事件
     */
    close() {
      if (this.previewQuestions.length > 0) {
        this.$confirm('您还有未处理的题目，确定要关闭吗？建议先采用或弃用所有题目', '提示', {
          confirmButtonText: '确定关闭',
          cancelButtonText: '取消',
          type: 'warning',
          distinguishCancelAndClose: true,
          showClose: false
        }).then(() => {
          this.$emit('close');
        }).catch(() => {
          // 用户取消关闭，不执行任何操作
        });
      } else {
        this.$emit('close');
      }
    },

    /**
     * 格式化日期字符串
     * @param {string} dateString - 日期字符串
     * @returns {string} - 格式化后的日期字符串
     */
    formatDate(dateString) {
      if (!dateString) return '未知';
      const date = new Date(dateString);
      return date.toLocaleDateString('zh-CN', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit'
      }).replace(/\//g, '-');
    },

    /**
     * 判断题目类型是否已选择
     * @param {string} type - 题目类型
     * @returns {boolean} - 已选择标志
     */
    isTypeSelected(type) {
      return this.config.questionTypes[type] > 0;
    },

    /**
     * 切换题目类型选择状态
     * @param {string} type - 题目类型
     */
    toggleQuestionType(type) {
      if (this.isTypeSelected(type)) {
        this.$delete(this.config.questionTypes, type);
      } else {
        // 检查添加此题型是否会超出30题的限制
        if (this.totalQuestions + 1 > 30) {
          this.$notify({
            title: '已达上限',
            message: '最多只能生成30道题，请减少已选题型数量后再添加',
            type: 'warning'
          });
          return;
        }
        this.$set(this.config.questionTypes, type, 1);
      }
    },

    /**
     * 增加某类型题目的数量
     * @param {string} type - 题目类型
     */
    incrementType(type) {
      if (this.totalQuestions >= 30) {
        this.$notify({
          title: '已达上限',
          message: '最多只能生成30道题，请减少其他题型数量后再增加',
          type: 'warning'
        });
        return;
      }
      
      // 移除单个题型数量上限为10题的限制
      this.$set(this.config.questionTypes, type, this.config.questionTypes[type] + 1);
    },

    /**
     * 减少某类型题目的数量
     * @param {string} type - 题目类型
     */
    decrementType(type) {
      if (this.config.questionTypes[type] > 1) {
        this.$set(this.config.questionTypes, type, this.config.questionTypes[type] - 1);
      } else {
        this.$delete(this.config.questionTypes, type);
      }
    },

    /**
     * 获取题目类型描述
     * @param {string} type - 题目类型
     * @returns {string} - 题目类型描述
     */
    getTypeDescription(type) {
      const descriptions = {
        single: '选择一个正确答案',
        multiple: '选择多个正确答案',
        truefalse: '判断陈述是否正确',
        fillblank: '填写空白处的答案',
        short_answer: '简要回答或分析问题'
      };
      return descriptions[type] || '';
    },

    /**
     * 获取题目类型名称缩写
     * @param {string} type - 题目类型
     * @returns {string} - 题目类型名称缩写
     */
    getTypeName(type) {
      const map = {
        single: '单选',
        multiple: '多选',
        truefalse: '判断',
        fillblank: '填空',
        short_answer: '简答'
      };
      return map[type] || type;
    },

    /**
     * 获取难度级别名称
     * @param {string} difficulty - 难度级别
     * @returns {string} - 难度级别名称
     */
    getDifficultyName(difficulty) {
      return this.difficultyOptions[difficulty] || difficulty;
    },

    /**
     * 获取难度级别样式
     * @param {string} difficulty - 难度级别
     * @returns {Object} - 包含背景色和文字颜色的样式对象
     */
    getDifficultyStyle(difficulty) {
      return {
        backgroundColor: this.difficultyColors[difficulty] || '#6B7280',
        color: 'white'
      };
    },

    /**
     * 格式化题目的正确答案显示
     * @param {Object} question - 题目对象
     * @returns {string} - 格式化后的正确答案
     */
    formatAnswer(question) {
      if (!question.correct_answer) return '';
      const opts = question.optionsKV || [];
      
      // 单选题处理
      if (question.typeLabel === '单选' || question.typeLabel === '单选题') {
        const ans = question.correct_answer.split(',')[0].trim();
        const found = opts.find(opt => opt.key === ans);
        return found ? `${found.key}. ${found.value}` : ans;
      }
      
      // 多选题处理
      if (question.typeLabel === '多选' || question.typeLabel === '多选题') {
        return question.correct_answer.split(',').map(ans => {
          const found = opts.find(opt => opt.key === ans.trim());
          return found ? `${found.key}. ${found.value}` : ans.trim();
        }).join('，');
      }
      
      // 判断题处理
      if (question.typeLabel === '判断' || question.typeLabel === '判断题') {
        // 如果答案是A或B
        if (question.correct_answer === 'A' || question.correct_answer === 'B') {
          const found = opts.find(opt => opt.key === question.correct_answer);
          return found ? `${found.key}. ${found.value}` : question.correct_answer;
        }
        // 如果答案是"正确"或"错误"
        const found = opts.find(opt => opt.value.includes(question.correct_answer) || 
                                       question.correct_answer.includes(opt.value));
        return found ? `${found.key}. ${found.value}` : question.correct_answer;
      }
      
      // 填空题处理
      if (question.typeLabel === '填空' || question.typeLabel === '填空题') {
        return question.correct_answer;
      }
      
      // 默认返回原始答案
      return question.correct_answer;
    },

    /**
     * 辅助方法：标准化选项
     * @param {string|Array} options - 选项文本或选项数组
     * @param {number} questionType - 题目类型
     * @returns {Array} - 标准化后的选项数组
     */
    formattedOptions(options, questionType) {
      if (!options) return [];
      // 判断题特殊处理
      if (questionType === 3) {
        let arr = [];
        if (Array.isArray(options)) {
          arr = options;
        } else if (typeof options === 'string') {
          // 兼容['正确','错误']字符串或A.正确\nB.错误
          try {
            if (options.trim().startsWith('[')) {
              arr = JSON.parse(options);
            } else {
              arr = options.split(/[,，、\n]/).map(s => s.replace(/^([A-B]\.|[A-B]\.)/, '').trim()).filter(Boolean);
            }
          } catch {
            arr = options.split(/[,，、\n]/).map(s => s.replace(/^([A-B]\.|[A-B]\.)/, '').trim()).filter(Boolean);
          }
        }
        // 保证有两个选项
        if (arr.length < 2) arr = ['正确', '错误'];
        return [
          { key: '正确', text: arr[0] || '正确' },
          { key: '错误', text: arr[1] || '错误' }
        ];
      }
      // 选择题处理（A/B/C/D...）
      let optionList = Array.isArray(options)
        ? options
        : typeof options === 'string'
          ? options.split('\n').map(s => s.trim()).filter(Boolean)
          : [];
      return optionList.map((text, index) => ({
        key: String.fromCharCode(65 + index),
        text: String(text).replace(/^([A-D]\.)/, '').trim()
      }));
    },

    /**
     * 判断选项是否为正确答案
     * @param {Object} question - 题目对象
     * @param {string} optionKey - 选项键值
     * @returns {boolean} - 是否为正确答案
     */
    isCorrectOption(question, optionKey) {
      // 没有正确答案信息，返回false
      if (!question.correct_answer) return false;
      
      // 单选题或多选题
      if (question.typeLabel === '单选' || question.typeLabel === '单选题' || 
          question.typeLabel === '多选' || question.typeLabel === '多选题') {
        // 处理正确答案格式，可能是A,B,C或单个字母A
        const correctAnswers = question.correct_answer.split(',').map(a => a.trim());
        return correctAnswers.includes(optionKey);
      }
      
      // 判断题
      if (question.typeLabel === '判断' || question.typeLabel === '判断题') {
        // 获取当前选项
        const opt = (question.optionsKV || []).find(o => o.key === optionKey);
        console.log('opt', opt);
        if (!opt) return false;
        
        // 简单情况：直接比较选项键与正确答案
        if (question.correct_answer === optionKey) {
          return true;
        }

        // 直接比较生成的题目答案和optionKV中的value值
        if (question.correct_answer === opt.value) {
          return true;
        }
        
        // 处理"正确"/"错误"值的情况
        if ((opt.value === '正确' && question.correct_answer.includes('正确')) || 
            (opt.value === '错误' && question.correct_answer.includes('错误'))) {
          return true;
        }
        
        // 处理答案是A/B且选项是正确/错误的情况
        if ((question.correct_answer === 'A' && opt.value === '正确') ||
            (question.correct_answer === 'B' && opt.value === '错误')) {
          return true;
        }
        
        return false;
      }
      
      return false;
    },

    /**
     * 获取某类型题目的预览数量
     * @param {string} type - 题目类型
     * @returns {number} - 预览数量
     */
    getPreviewCount(type) {
      return this.previewQuestions.filter(q => q.type === type).length;
    },

    /**
     * 显示使用教程
     */
    showTutorial() {
      this.$emit('show-tutorial');
    },

    /**
     * 获取AI建议的关键词
     */
    async fetchSuggestedKeywords() {
      const cache = window.__AI_BANK_ANALYSIS_CACHE__;
      const key = this.analysisCacheKey;
      // 如果已有缓存则直接用
      if (this.suggestedKeywords && this.suggestedKeywords.length > 0) return;
      if (cache[key] && cache[key].suggestedKeywords && cache[key].suggestedKeywords.length > 0) {
        this.suggestedKeywords = cache[key].suggestedKeywords;
        return;
      }
      // 否则请求AI
      await this.fetchKeywordsFromAI();
    },

    /**
     * 从AI获取关键词建议
     */
    async fetchKeywordsFromAI() {
      const loadingToast = this.$notify({
        title: 'AI分析中',
        message: '正在分析题库获取关键词建议...',
        type: 'info',
      });

      try {
        const prompt = `
          请根据以下题库内容，分析并返回最相关的关键词建议。
          要求：
          1. 每个关键词不得少于或者超过4-6个字
          2. 关键词要具体且相关
          3. 必须返回16个关键词，格式必须是JSON数组：["关键词1", "关键词2", "关键词3", "关键词4", "关键词5", "关键词6", "关键词7", "关键词8", "关键词9", "关键词10", "关键词11", "关键词12", "关键词13", "关键词14", "关键词15", "关键词16"]
          4. 不要返回任何其他解释性文字
        `;

        const bankData = { bank: this.bank };
        let aiResponse = await callSiliconAI(prompt, bankData, systemPrompt);
        
        let parsed;
        try {
          // 清理可能的Markdown代码块和其他非JSON内容
          if (typeof aiResponse === 'string') {
            console.log('原始AI响应:', aiResponse);
            
            // 移除Markdown代码块标记
            aiResponse = aiResponse
              .replace(/```json\s*/g, '')  // 移除开始的```json
              .replace(/```\s*$/g, '')     // 移除结束的```
              .replace(/```/g, '')         // 移除任何剩余的```标记
              .trim();
            
            // 尝试查找有效的JSON数组
            const jsonMatch = aiResponse.match(/\[\s*"[^"]*"(?:\s*,\s*"[^"]*")*\s*\]/);
            if (jsonMatch) {
              aiResponse = jsonMatch[0];
            }
            
            console.log('处理后的AI响应:', aiResponse);
          }
          
          // 尝试解析JSON
          parsed = typeof aiResponse === 'string' ? JSON.parse(aiResponse) : aiResponse;
          
          // 验证结果是否符合要求
          if (!Array.isArray(parsed)) {
            console.error('解析结果不是数组:', parsed);
            
            // 如果结果不是数组但有内容，尝试提取关键词
            if (parsed && typeof parsed === 'object') {
              // 尝试从对象中提取可能的关键词数组
              for (const key in parsed) {
                if (Array.isArray(parsed[key])) {
                  parsed = parsed[key];
                  break;
                }
              }
            } else if (typeof aiResponse === 'string') {
              // 尝试从文本中提取关键词
              const keywords = aiResponse.match(/"([^"]*)"/g);
              if (keywords && keywords.length > 0) {
                parsed = keywords.map(k => k.replace(/"/g, ''));
              } else {
                // 最后的尝试：按逗号分割
                parsed = aiResponse.split(/[,，、]/).map(k => k.trim()).filter(Boolean);
              }
            }
          }
        } catch (error) {
          console.error('解析AI响应时出错:', error);
          console.log('原始AI响应:', aiResponse);
          
          // 创建默认关键词
          parsed = [
            "知识点一", "知识点二", "知识点三", "知识点四",
            "概念术语", "重要公式", "核心原理", "关键技巧",
            "方法论述", "基本理论", "应用实例", "题型分析",
            "解题思路", "常见错误", "重点归纳", "考试技巧"
          ];
          
          this.$notify({
            title: '解析失败',
            message: '已使用默认关键词，您可以点击刷新重试',
            type: 'warning'
          });
        }

        this.suggestedKeywords = parsed;
        
        // 更新缓存
        const cache = window.__AI_BANK_ANALYSIS_CACHE__ || {};
        window.__AI_BANK_ANALYSIS_CACHE__ = cache;
        
        const key = this.analysisCacheKey;
        if (cache[key]) {
          cache[key].suggestedKeywords = this.suggestedKeywords;
        } else {
          cache[key] = { suggestedKeywords: this.suggestedKeywords };
        }

        this.$notify({
          title: '分析完成',
          message: '已获取AI建议关键词',
          type: 'success'
        });
      } catch (error) {
        console.error('获取关键词建议完整错误:', error);
        this.$notify.error('获取关键词建议失败: ' + (error.message || '未知错误'));
      } finally {
        this.$notify.close(loadingToast.id);
      }
    },

    /**
     * 显示智能关键词建议（灯泡按钮）
     */
    async showSmartSuggestions() {
      // 添加加载类
      const button = document.querySelector('.btn-smart-suggest');
      if (button) button.classList.add('loading');
      
      this.$notify({
        title: '智能建议',
        message: 'AI正在分析题库内容，为您推荐关键词',
        type: 'info'
      });
      
      // 先获取关键词
      await this.fetchKeywordsFromAI();
      
      // 移除加载类
      if (button) button.classList.remove('loading');
      
      if (this.suggestedKeywords && this.suggestedKeywords.length > 0) {
        // 随机选择3-5个关键词
        const shuffled = [...this.suggestedKeywords].sort(() => 0.5 - Math.random());
        const count = 3 + Math.floor(Math.random() * 3); // 3-5个
        const selected = shuffled.slice(0, Math.min(count, shuffled.length));
        
        // 获取当前已有的关键词
        const currentKeywords = this.config.keywords.split(',')
          .map(k => k.trim())
          .filter(k => k);
          
        // 添加新关键词（避免重复）
        const newKeywords = selected.filter(k => !currentKeywords.includes(k));
        if (newKeywords.length > 0) {
          // 如果当前已有关键词且新关键词不为空，添加逗号分隔符
          if (currentKeywords.length > 0) {
            this.config.keywords = currentKeywords.join(', ') + ', ' + newKeywords.join(', ');
          } else {
            this.config.keywords = newKeywords.join(', ');
          }
          
          this.$notify({
            title: '已添加智能关键词',
            message: `已自动添加${newKeywords.length}个AI推荐的关键词`,
            type: 'success'
          });
          
          // 添加高亮动画到所有关键词标签
          this.$nextTick(() => {
            const tags = document.querySelectorAll('.keyword-tag');
            tags.forEach(tag => {
              tag.classList.add('tag-highlight');
              setTimeout(() => {
                tag.classList.remove('tag-highlight');
              }, 1000);
            });
          });
          
          // 触发关键词分析
          this.analyzeKeywords();
        } else {
          this.$notify({
            title: '智能关键词',
            message: '没有新的关键词可添加',
            type: 'info'
          });
        }
      }
    },

    /**
     * 刷新建议关键词（强制AI重新分析）
     */
    async refreshSuggestions() {
      if (this.isRefreshingSuggestions) return;
      
      this.isRefreshingSuggestions = true;
      
      // 不清空关键词，只是应用加载状态
      this.$notify({
        title: '刷新中',
        message: '正在获取新的AI建议关键词',
        type: 'info'
      });
      
      try {
        // 强制刷新分析
        await this.fetchKeywordsFromAI();
        
        this.$notify({
          title: '刷新成功',
          message: '已获取新的AI智能推荐关键词',
          type: 'success',
          customClass: 'notification-animated'
        });
      } catch (error) {
        this.$notify.error('刷新关键词失败: ' + error.message);
      } finally {
        this.isRefreshingSuggestions = false;
      }
    },

    /**
     * 应用建议关键词
     * @param {string} keyword - 关键词
     */
    applyKeyword(keyword) {
      const currentKeywords = this.config.keywords.split(',').map(k => k.trim()).filter(k => k);
      if (!currentKeywords.includes(keyword)) {
        currentKeywords.push(keyword);
        this.config.keywords = currentKeywords.join(', ');
        
        // 添加动画效果
        this.$nextTick(() => {
          const lastTag = document.querySelector('.keyword-tag:last-child');
          if (lastTag) {
            // 添加多级动画效果
            lastTag.classList.add('tag-highlight');
            lastTag.style.boxShadow = `0 0 0 3px rgba(67, 97, 238, 0.3)`;
            
            // 设定定时器移除强调效果
            setTimeout(() => {
              lastTag.classList.remove('tag-highlight');
              
              // 淡出阴影效果
              setTimeout(() => {
                lastTag.style.boxShadow = 'none';
              }, 300);
            }, 1000);
          }
        });
        
        // 更现代的反馈通知
        this.keywordFeedback = `<i class="fas fa-check-circle"></i> 已添加关键词: <span class="keyword-highlight">${keyword}</span>`;
        this.keywordFeedbackIcon = 'fa-check-circle';
        
        // 自动隐藏反馈
        setTimeout(() => {
          this.keywordFeedback = '';
        }, 3000);
      }
    },

    /**
     * 分析关键词并给出反馈
     */
    analyzeKeywords() {
      const keywords = this.config.keywords.split(',').map(k => k.trim()).filter(k => k);
      
      if (keywords.length > 3) {
        this.keywordFeedback = '关键词数量充足，AI将生成更精准的题目';
        this.keywordFeedbackIcon = 'fa-check-circle';
      } else if (keywords.length > 0) {
        this.keywordFeedback = '可以添加更多关键词提高准确性';
        this.keywordFeedbackIcon = 'fa-lightbulb';
      } else {
        this.keywordFeedback = '';
      }
    },

    /**
     * 尝试从缓存加载分析结果，否则自动分析
     */
    tryLoadAnalysisFromCache() {
      const cache = window.__AI_BANK_ANALYSIS_CACHE__;
      const key = this.analysisCacheKey;
      if (cache[key]) {
        const { analysis, suggestedKeywords, recommendationOptions } = cache[key];
        this.aiAnalysisResult = analysis;
        this.suggestedKeywords = suggestedKeywords || [];
        this.recommendationOptions = recommendationOptions || this.recommendationOptions;
      } else {
        this.analyzeBank();
      }
    },

    /**
     * 分析题库内容，支持强制刷新
     * @param {boolean} forceRefresh - 是否强制刷新分析
     */
    async analyzeBank(forceRefresh = false) {
      // 检查缓存，如果不强制刷新且已有缓存，则使用缓存
      const cache = window.__AI_BANK_ANALYSIS_CACHE__ || {};
      const key = this.analysisCacheKey;
      
      if (!forceRefresh && cache[key]) {
        // 已缓存，直接用
        const { analysis, suggestedKeywords, recommendationOptions } = cache[key];
        this.aiAnalysisResult = analysis;
        this.suggestedKeywords = suggestedKeywords || [];
        this.recommendationOptions = recommendationOptions || this.recommendationOptions;
        return;
      }
      
      // 不使用缓存，为了避免重复逻辑，这里无需再次调用API
      // 因为isAnalyzing的变化已经由子组件通过.sync修饰符处理
      // API的调用由GenerateBankCard组件完成
    },

    /**
     * 纯文本格式化（换行转空格）
     * @param {string} text - 文本内容
     * @returns {string} - 格式化后的文本
     */
    formatPlainText(text) {
      // 简单替换换行符为空格（保持单行显示）
      return text.replace(/\n/g, ' ')
        .replace(/\s+/g, ' ')
        .trim();
    },

    /**
     * 格式化分析结果
     * @returns {string} - 格式化后的分析结果
     */
    formatAnalysisResult() {
      const r = this.aiAnalysisResult;
      return `
        知识点覆盖: ${r.knowledgeCoverage}%。缺失: ${r.missingKnowledgePoints.join('、')}
        难度分析: ${r.difficultyScore}/100。评价: ${r.difficultyEvaluation}
        题型多样性: ${r.questionTypeDiversity}。缺失题型: ${r.missingQuestionTypes.join('、')}
        创新度评分: ${r.innovationScore}/100。评价: ${r.innovationEvaluation}
        综合质量: ${r.overallQualityScore}/100。评价: ${r.overallQualityEvaluation}
        AI建议: ${r.aiSuggestions.join(' ')}
      `;
    },

    /**
     * 应用推荐配置
     * @param {Object} option - 推荐配置选项
     */
    applyRecommendation(option) {
      // 计算选择该推荐后的总题目数
      const totalCount = Object.values(option.types).reduce((sum, count) => sum + count, 0);
      if (totalCount > 30) {
        this.$notify({
          title: '题目超限',
          message: '该推荐方案共包含' + totalCount + '道题，超过了30题上限，请选择题目较少的方案',
          type: 'warning'
        });
        return;
      }
      this.toggleRecommendation(option);
    },

    /**
     * 优化已生成的题目
     */
    optimizeQuestions() {
      if (this.previewQuestions.length === 0) {
        this.$notify({
          title: '提示',
          message: '请先生成题目再进行优化',
          type: 'warning'
        });
        return;
      }

      this.$notify({
        title: 'AI优化功能',
        message: 'AI优化功能即将上线',
        type: 'info'
      });

    },

    /**
     * 开始生成题目（多轮补全，自动修复JSON，兼容数据库格式，标准化展示）
     */
    async startGeneration() {
      // 检查题目数量是否超过限制
      if (this.totalQuestions > 30) {
        this.$notify({
          title: '题目超限',
          message: '最多只能生成30道题，请减少题型数量后再试',
          type: 'warning'
        });
        return;
      }

      this.generating = true;
      this.isGenerating = true;
      this.progress = 0;
      this.error = null;
      this.previewQuestions = [];
      this.aiQuestion = [];
      this.showQuestions = false;
      this.thinkingText = this.thinkingTexts[0];
      let textIndex = 0;
      let progressTimer = null;
      let aiDone = false;
      let aiResultQuestions = [];
      const minThinkingMs = 2500; // 最短思考时间 2.5秒
      const startTime = Date.now();
      // 进度条动画
      progressTimer = setInterval(() => {
        if (this.progress < 100) {
          this.progress = Math.min(this.progress + Math.floor(Math.random() * 5) + 2, 99);
          const step = Math.floor((this.progress / 100) * this.thinkingTexts.length);
          textIndex = Math.min(step, this.thinkingTexts.length - 1);
          this.thinkingText = this.thinkingTexts[textIndex];
        }
      }, 400);
      this.thinkingInterval = setInterval(() => {}, 2000);

      // 多轮补全逻辑
      let allQuestions = [];
      let tries = 0;
      const maxTries = 8;
      const configTypes = { ...this.config.questionTypes };
      const totalNeeded = Math.min(this.totalQuestions, 30); // 确保不超过30题
      const typeNumMap = { single: 0, multiple: 1, fillblank: 2, truefalse: 3, short_answer: 4 };
      const typeZhMap = { single: '单选题', multiple: '多选题', fillblank: '填空题', truefalse: '判断题', short_answer: '简答题' };
      // --- AI生成题目主流程 ---
      const aiPromise = (async () => {
        while (tries < maxTries) {
          let existText = '';
          if (allQuestions.length > 0) {
            existText = `\n已生成题目如下（请勿重复）：\n${JSON.stringify(allQuestions.map(q => ({content: q.content, type: q.type})))}\n`;
          }
          const typeDescArr = Object.entries(this.config.questionTypes)
            .filter(([type, count]) => count > 0)
            .map(([type, count]) => `${typeZhMap[type]}（type:${typeNumMap[type]}）：${count}道`);
          const typeDesc = typeDescArr.join('\n');
          const keywords = this.config.keywords;
          const difficulty = this.difficultyOptions[this.config.difficulty] || this.config.difficulty;
          const style = this.styleOptions[this.config.style] || this.config.style;
          const prompt = `请严格按照如下要求生成${totalNeeded}道题目，所有输出必须为JSON数组格式，且每道题包含以下字段：\n- content: 题干内容\n- type: 题型编号（0单选，1多选，2填空，3判断，4简答）\n- difficulty: 难度（1-10整数）\n- options: 选项（单选(逗号分隔)/多选/判断为字符串，填空/简答为\"\"）\n- parse: 答案解析\n- answer: 正确答案（单选/多选为A/B/C等，判断为\"正确/错误\"，填空/简答为文本）\n\n要求：\n1. 必须严格生成如下题型分布：${typeDesc}\n2. 总题数：${totalNeeded}\n3. 题目内容、题型、数量、难度、风格、关键词必须与上述配置完全一致，题目内容不能重复。\n4. 只返回JSON数组，不要任何解释性文字或注释。\n5. 题型数量必须与要求完全一致，不能多也不能少。\n6. 输出内容必须能被JSON.parse直接解析。\n${existText}\n配置：\n难度：${difficulty}\n风格：${style}\n关键词：${keywords}，单选题和多选题必须至少4个选项并且单选题只有一个答案，多选题有多个答案多个答案用逗号隔开，判断题两个选项，填空题没有选项只有答案和解析它的多个答案用逗号隔开，还有就是简单题它是没有选项和答案的只有答案解析
               题型模板如下：
            [
              // 单选题
              {
                "content": "下列哪一项是人工智能的英文翻译？",
                "type": 0,
                "difficulty": 5,
                "options": "Artificial Intelligence,Human Intelligence,Machine Learning,Robot Thinking",
                "parse": "人工智能的英文是 Artificial Intelligence。",
                "answer": "Artificial Intelligence"
              },
              // 多选题
              {
                "content": "以下哪些属于机器学习的常用算法？",
                "type": 1,
                "difficulty": 6,
                "options": "决策树,支持向量机,线性回归,冒泡排序",
                "parse": "前三项是机器学习算法，冒泡排序是排序算法。",
                "answer": "决策树,支持向量机,线性回归"
              },
              // 判断题
              {
                "content": "深度学习是机器学习的一个分支。",
                "type": 3,
                "difficulty": 4,
                "options": "正确,错误",
                "parse": "深度学习确实是机器学习的一个分支。",
                "answer": "正确"
              },
              // 填空题
              {
                "content": "人工智能的英文缩写是____。",
                "type": 2,
                "difficulty": 3,
                "options": "",
                "parse": "人工智能的英文缩写是 AI。",
                "answer": "AI"
              },
              // 简答题
              {
                "content": "请简述人工智能的主要应用领域。",
                "type": 4,
                "difficulty": 7,
                "options": "",
                "parse": "人工智能应用于医疗、金融、自动驾驶、智能家居等领域。",
                "answer": ""
              }
            ] 
          
            题型要求:
                1. 【单选题】(type=0): 
                  - 必须是问句形式
                  - options格式为"选项1,选项2,选项3,选项4"，逗号分隔
                  - answer为选项内容字符串
                
                2. 【多选题】(type=1): 
                  - 必须是问句形式
                  - options格式为"选项1,选项2,选项3,选项4"，逗号分隔
                  - answer为多个正确选项内容，用逗号连接
                
                3. 【填空题】(type=2):
                  - 【重要】必须在题目内容中明确包含下划线"____"表示空白处，有几个答案就有几个下划线
                  - 不能是问句形式，必须是陈述句中包含空白需要填写
                  - answer为填入空白处的正确答案，有几个下划线就有几个答案用逗号隔开
                
                4. 【判断题】(type=3):
                  - 必须是明确的陈述句，不能是问句
                  - options固定为"正确,错误"
                  - answer必须是"正确"或"错误"
                  - 【严禁】不能包含下划线"____"或任何填空符号
                
                5. 【简答题】(type=4):
                  - 必须是开放式问题
                  - answer可以为空，但必须提供详细的parse(参考解析)
                
                确保所有题目符合教育测试标准，内容准确，表述清晰，答案无歧义
                确保新题目与提供的参考资料内容高度相关,切记不要重复原题的知识点
            `;
          
          
          
          let aiResult, aiText, questions;
          try {
            aiResult = await callSiliconAI(prompt, { bank: this.bank }, systemPrompt);
            aiText = typeof aiResult === 'string' ? aiResult.trim() : aiResult;
            if (typeof aiText === 'string') {
              let fixed = aiText.trim();
              if (!fixed.startsWith('[')) fixed = '[' + fixed;
              if (!fixed.endsWith(']')) fixed = fixed + ']';
              try {
                questions = JSON.parse(fixed);
              } catch (e1) {
                const lastBracket = fixed.lastIndexOf(']');
                if (lastBracket > 0) {
                  try {
                    questions = JSON.parse(fixed.slice(0, lastBracket + 1));
                  } catch (e2) {
                    questions = [];
                  }
                } else {
                  questions = [];
                }
              }
            } else {
              questions = aiText;
            }
            if (!Array.isArray(questions)) questions = [questions];
          } catch (e) {
            questions = [];
          }
          questions = questions.filter(q => q && q.content && typeof q.type !== 'undefined');
          const existingContents = new Set(allQuestions.map(q => q.content));
          const newQuestions = questions.filter(q => q.content && !existingContents.has(q.content));
          allQuestions.push(...newQuestions);
          let enough = true;
          for (const type in configTypes) {
            const count = allQuestions.filter(q => {
              if (typeof q.type === 'number') return typeNumMap[type] === q.type;
              return type === q.type;
            }).length;
            if (count < configTypes[type]) { enough = false; break; }
          }
          if (enough && allQuestions.length >= totalNeeded) break;
          tries++;
        }
        // 标准化并裁剪
        let finalQuestions = [];
        for (const type in configTypes) {
          const group = allQuestions.filter(q => {
            if (typeof q.type === 'number') return typeNumMap[type] === q.type;
            return type === q.type;
          });
          finalQuestions = finalQuestions.concat(group.slice(0, configTypes[type]));
        }
        finalQuestions = finalQuestions.slice(0, totalNeeded);
        // 题目格式标准化，兼容数据库格式
        this.aiQuestion = finalQuestions.map(q => {
          let options = q.options;
          if (options === null || options === undefined) options = '';
          let optionsList = [];
          let correct_answer = q.answer || q.correct_answer || '';
          const typeMap = { 0: 'single', 1: 'multiple', 2: 'fillblank', 3: 'truefalse', 4: 'short_answer' };
          const type = typeof q.type === 'number' ? typeMap[q.type] : q.type;
          const typeNumMap = { single: 0, multiple: 1, fillblank: 2, truefalse: 3, short_answer: 4 };
          const typeNum = typeof q.type === 'number' ? q.type : typeNumMap[type];
          const typeLabelMap = { 0: '单选', 1: '多选', 2: '填空', 3: '判断', 4: '简答', single: '单选', multiple: '多选', fillblank: '填空', truefalse: '判断', short_answer: '简答' };
          const typeLabel = typeLabelMap[q.type] || typeLabelMap[type];
          let cleanContent = q.content || '';
          cleanContent = cleanContent.replace(/^判断[:：\s]*/i, '').replace(/^判断正误[:：\s]*/i, '');
          cleanContent = cleanContent.replace(/^(单选题|多选题|判断题|填空题|简答题|填空|简答)[:：\s]*/i, '');
          let optionsKV = [];
          if (typeLabel === '单选') {
            let arr = parseOptions(options);
            if (arr.length < 4) { while (arr.length < 4) arr.push(''); }
            optionsList = arr.map((text, idx) => ({ key: String.fromCharCode(65 + idx), value: typeof text === 'string' ? text.replace(/^([A-D]\.)/, '').replace(/^"|"$/g, '').trim() : text }));
            optionsKV = optionsList;
            options = arr.join(',');
            if (correct_answer && optionsList.length) {
              let idx = optionsList.findIndex(opt => opt.value === correct_answer || opt.key === correct_answer);
              if (idx >= 0) correct_answer = optionsList[idx].key;
              else if (/^[A-D]$/.test(correct_answer)) correct_answer = correct_answer;
              else correct_answer = '';
            }
          }
          else if (typeLabel === '多选') {
            let arr = parseOptions(options);
            optionsList = arr.map((text, idx) => ({ key: String.fromCharCode(65 + idx), value: typeof text === 'string' ? text.replace(/^([A-D]\.)/, '').replace(/^"|"$/g, '').trim() : text }));
            optionsKV = optionsList;
            options = arr;
            if (correct_answer && optionsList.length) {
              let ansArr = (correct_answer || '').split(/[，,、]/).map(s => s.trim()).filter(Boolean);
              let letterArr = ansArr.map(ans => {
                let idx = -1;
                if (/^[A-D]$/.test(ans)) idx = ans.charCodeAt(0) - 65;
                else idx = optionsList.findIndex(opt => opt.value === ans || opt.key === ans);
                if (idx >= 0 && optionsList[idx]) return optionsList[idx].key;
                return null;
              }).filter(Boolean);
              correct_answer = letterArr.join(',');
            }
          }
          else if (typeLabel === '判断') {
            let arr = parseOptions(options);
            if (arr.length < 2) arr = ['正确', '错误'];
            optionsKV = [
              { key: 'A', value: typeof arr[0] === 'string' ? arr[0].replace(/^"|"$/g, '').trim() : arr[0] || '正确' },
              { key: 'B', value: typeof arr[1] === 'string' ? arr[1].replace(/^"|"$/g, '').trim() : arr[1] || '错误' }
            ];
            if (correct_answer) {
              if (correct_answer.includes('正确')) correct_answer = '正确';
              else if (correct_answer.includes('错误')) correct_answer = '错误';
              else if (correct_answer === 'A') correct_answer = '正确';
              else if (correct_answer === 'B') correct_answer = '错误';
              else correct_answer = '';
            }
          }
          else {
            optionsKV = [];
          }
          return {
            ...q,
            type,
            typeLabel,
            typeNum,
            optionsKV,
            difficultyLabel: this.getDifficultyLabelByNum(q.difficulty),
            difficultyColor: this.getDifficultyColorByNum(q.difficulty),
            correct_answer,
            options: options || '',
            content: cleanContent,
          };
        });
        aiResultQuestions = this.aiQuestion.map(q => ({ ...q }));
        aiDone = true;
      })();
      // --- 进度条和AI并行 ---
      // 等待AI和最短思考时间都完成
      await Promise.all([
        aiPromise,
        new Promise(resolve => setTimeout(resolve, minThinkingMs))
      ]);
      // 如果进度条还没到100%，补足动画
      if (this.progress < 100) {
        await new Promise(resolve => {
          const timer = setInterval(() => {
            if (this.progress < 100) {
              this.progress = Math.min(this.progress + 8, 100);
            }
            if (this.progress >= 100) {
              clearInterval(timer);
              resolve();
            }
          }, 60);
        });
      }
      // 只有此时才展示题目
      clearInterval(this.thinkingInterval);
      clearInterval(progressTimer);
      this.generating = false;
      this.progress = 100;
      this.thinkingText = this.thinkingTexts[this.thinkingTexts.length - 1];
      this.previewQuestions = aiResultQuestions;
      this.showQuestions = true;
      this.generationCompleted = true; // 标记生成已完成但题目未处理
      // 校验题型和数量
      let enough = true;
      for (const type in configTypes) {
        const count = this.previewQuestions.filter(q => q.type === type).length;
        if (count < configTypes[type]) {
          enough = false;
          break;
        }
      }
      if (!enough || this.previewQuestions.length < totalNeeded) {
        this.$notify({
          title: '生成不完整',
          message: `AI未能生成全部题目，请减少题目数量或重试。`,
          type: 'warning'
        });
      }
      
      // 在处理完所有题目后调用打印函数
      this.printGeneratedQuestions();
    },

    /**
     * 生成一批题目
     * @param {boolean} forceComplete - 是否强制完成所有题目生成
     */
    generateQuestionsBatch(forceComplete = false) {
      const typesToGenerate = Object.entries(this.config.questionTypes)
          .filter(([type, count]) => {
            const generatedCount = this.previewQuestions.filter(q => q.type === type).length;
            return generatedCount < count;
          });

      if (typesToGenerate.length === 0) return;

      const batchSize = forceComplete ? typesToGenerate.length : Math.min(3, typesToGenerate.length);

      for (let i = 0; i < batchSize; i++) {
        const [type, count] = typesToGenerate[i];
        const generatedCount = this.previewQuestions.filter(q => q.type === type).length;

        if (generatedCount < count) {
          this.previewQuestions.push(this.generateQuestion(type));
        }
      }
    },

    /**
     * 生成单个题目
     * @param {string} type - 题目类型
     * @returns {Object} - 生成的题目对象
     */
    generateQuestion(type) {
      const questionId = `gen-${Date.now()}-${Math.floor(Math.random() * 1000)}`;
      const baseQuestion = {
        question_id: questionId,
        bank_id: this.bank.bankId,
        content: this.generateQuestionContent(type),
        type,
        difficulty: this.config.difficulty,
        style: this.config.style,
        generated: true,
        parse: this.generateAnalysisContent(type)
      };

      switch (type) {
        case 'single':
          return {
            ...baseQuestion,
            options: this.generateOptions(4),
            correct_answer: ['A', 'B', 'C', 'D'][Math.floor(Math.random() * 4)]
          };
        case 'multiple':
          const correctCount = Math.min(3, 2 + Math.floor(Math.random() * 2));
          const correctAnswers = ['A', 'B', 'C', 'D']
              .sort(() => 0.5 - Math.random())
              .slice(0, correctCount)
              .join('');

          return {
            ...baseQuestion,
            options: this.generateOptions(4),
            correct_answer: correctAnswers
          };
        case 'truefalse':
          return {
            ...baseQuestion,
            options: 'A.正确\nB.错误',
            correct_answer: Math.random() > 0.5 ? 'A' : 'B'
          };
        case 'fillblank':
          return {
            ...baseQuestion,
            correct_answer: '正确答案'
          };
        case 'short_answer':
          return {
            ...baseQuestion
          };
      }
    },

    /**
     * 生成题目的内容
     * @param {string} type - 题目类型
     * @returns {string} - 题目内容
     */
    generateQuestionContent(type) {
      const keyword = this.config.keywords || '编程知识';
      const typeMap = {
        single: [
          `关于${keyword}的描述中，哪一项是正确的？`,
          `在${keyword}中，以下哪种做法是最佳实践？`,
          `关于${keyword}的实现方式，以下说法错误的是？`
        ],
        multiple: [
          `关于${keyword}，以下哪些说法是正确的？`,
          `在${keyword}场景中，以下哪些做法是合适的？`,
          `以下哪些选项描述了${keyword}的正确特性？`
        ],
        truefalse: [
          `判断: ${keyword}的描述是否正确？`,
          `以下关于${keyword}的说法是否正确？`,
          `判断正误: ${keyword}`
        ],
        fillblank: [
          `请填写${keyword}中的空白处: _____`,
          `在${keyword}中，缺失的部分是: _____`,
          `完成${keyword}的表述: _____`
        ],
        short_answer: [
          `请简要分析${keyword}的主要特点和适用场景。`,
          `论述${keyword}在实际应用中的优势和局限性。`,
          `解释${keyword}的核心概念，并举例说明其应用。`
        ]
      };

      const options = typeMap[type] || typeMap.single;
      return options[Math.floor(Math.random() * options.length)];
    },

    /**
     * 生成题目的分析内容
     * @param {string} type - 题目类型
     * @returns {string} - 题目分析内容
     */
    generateAnalysisContent(type) {
      const keyword = this.config.keywords || '编程知识';
      const typeMap = {
        single: `本题考查${keyword}的基本概念。正确答案的分析过程如下...`,
        multiple: `本题考查${keyword}的综合理解。各选项分析如下...`,
        truefalse: `本题考查${keyword}的判断。正确理解应该是...`,
        fillblank: `本题考查${keyword}的具体应用。正确答案的依据是...`,
        short_answer: `本题考查${keyword}的综合分析。回答时应包含以下要点...`
      };
      return typeMap[type] || '这是题目的详细解析...';
    },

    /**
     * 生成选项文本
     * @returns {string} - 选项文本
     */
    generateOptionText() {
      const texts = [
        '正确选项描述',
        '常见错误描述',
        '部分正确但不完全',
        '完全错误的描述'
      ];
      return texts[Math.floor(Math.random() * texts.length)];
    },

    /**
     * 生成题目选项
     * @param {number} count - 选项数量
     * @returns {string} - 选项文本（多行格式）
     */
    generateOptions(count) {
      const options = [];
      for (let i = 0; i < count; i++) {
        const letter = String.fromCharCode(65 + i);
        options.push(`${letter}.${this.generateOptionText()}`);
      }
      return options.join('\n');
    },

    /**
     * 通用：将题目添加到题库（单个/批量都用这个）
     */
    async _acceptQuestionToBank(question) {
      const options = question.optionsKV.map(item => item.value).join(',');
      const dbQuestion = {
        bankId: this.bank.bankId,
        content: question.content,
        options,
        correctAnswer: question.correct_answer, // 修改 answer 为 correct_answer
        parse: question.parse,
        type: question.typeNum,
        difficulty: question.difficulty
      };
      try {
        const response = await addQuestion(dbQuestion);
        if (response.data.code === 200) {
          this.$store.commit('question/ADD_QUESTION', {
            ...dbQuestion,
            questionId: response.data.data?.questionId || Date.now()
          });
          // 新增：同步更新题库数量
          this.$store.commit('question/INCREMENT_BANK_QUESTION_COUNT', this.bank.bankId);
          return true;
        } else {
          this.$notify({
            title: '题目添加失败',
            message: response.data.msg || '题目添加到题库失败',
            type: 'error'
          });
          return false;
        }
      } catch (error) {
        console.error('添加题目失败:', error);
        this.$notify({
          title: '题目添加失败',
          message: '题目添加到题库失败',
          type: 'error'
        });
        return false;
      }
    },

    /**
     * 接受题目并添加到题库
     * @param {Object} question - 题目对象
     */
    async acceptQuestion(question) {
      // 打印题目信息（调试用）
      console.group('===== 接受的题目信息 =====');
      console.log('题干:', question.content);
      console.log('类型:', question.typeLabel, `(${question.type}, typeNum: ${question.typeNum})`);
      console.log('选项KV映射:', question.optionsKV);
      console.log('正确答案:', question.correct_answer);
      console.log('完整题目对象:', question);
      console.groupEnd();
      
      const ok = await this._acceptQuestionToBank(question);
      if (ok) {
        this.previewQuestions = this.previewQuestions.filter(q => q !== question);
        this.$notify({
          title: '题目已采用',
          message: '题目已添加到题库',
          type: 'success'
        });
        
        // 检查是否所有题目都已处理完
        if (this.previewQuestions.length === 0) {
          this.generationCompleted = false; // 允许重新生成
        }
      }
    },

    /**
     * 批量接受所有题目
     */
    async acceptAllQuestions() {
      // 弹出确认框
      this.$confirm('确定要批量接受所有题目吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        let successCount = 0;
        for (const q of [...this.previewQuestions]) {
          const ok = await this._acceptQuestionToBank(q);
          if (ok) successCount++;
        }
        this.previewQuestions = [];
        this.generationCompleted = false; // 重置状态，允许再次生成
        this.$notify({
          title: '批量操作完成',
          message: `已添加${successCount}道题目到题库`,
          type: 'success'
        });
      }).catch(() => {});
    },

    /**
     * 拒绝题目
     * @param {number} index - 题目在预览列表中的索引
     */
    rejectQuestion(index) {
      this.previewQuestions.splice(index, 1);
      
      // 检查是否所有题目都已处理完
      if (this.previewQuestions.length === 0) {
        this.generationCompleted = false; // 允许重新生成
      }
    },

    /**
     * 重新生成题目
     * @param {number} index - 题目在预览列表中的索引
     */
     async regenerateQuestion(index) {
      this.$notify({
        title: '正在重新生成题目',
        message: '请稍后...',
      });
      
      // 设置状态为正在重新生成
      this.regeneratingIndex = index;
      
      const oldQuestion = this.previewQuestions[index];
      const type = oldQuestion.type;
      const typeNumMap = { single: 0, multiple: 1, fillblank: 2, truefalse: 3, short_answer: 4 };
      const typeZhMap = { single: '单选题', multiple: '多选题', fillblank: '填空题', truefalse: '判断题', short_answer: '简答题' };
      // 新增：反向映射 - 从中文题型映射到英文键
      const typeZhToEnMap = { '单选题': 'single', '多选题': 'multiple', '填空题': 'fillblank', '判断题': 'truefalse', '简答题': 'short_answer' };
      
      // 处理类型映射，支持多种类型输入格式
      let mappedType = type;
      // 如果是中文名称，转换为英文键
      if (typeZhToEnMap[type]) {
        mappedType = typeZhToEnMap[type];
      }
      
      const typeNum = typeof mappedType === 'number' ? mappedType : typeNumMap[mappedType];
      const typeLabel = typeZhMap[mappedType] || (typeof type === 'string' ? type : undefined);
      const keywords = this.config.keywords;
      const difficulty = this.difficultyOptions[this.config.difficulty] || this.config.difficulty;
      const style = this.styleOptions[this.config.style] || this.config.style;
      const prompt = `请生成1道${typeLabel}，难度：${difficulty}，风格：${style}，关键词：${keywords}。输出JSON数组，字段为content、type、difficulty、options、parse、answer。不要解释。`;

      let aiResult, aiText, questions;
      try {
         const regenatPromp =`你是一个专业的智能题库生成助手。你的任务是根据用户的详细配置，严格生成指定数量和题型的题目。所有输出必须为JSON数组，且每道题包含content、type、difficulty、options、parse、answer字段。不要输出任何解释、注释或多余内容。务必保证JSON格式可直接被JSON.parse解析，题型数量必须与要求完全一致。
          题型模板如下：
            [
              // 单选题
              {
                "content": "下列哪一项是人工智能的英文翻译？",
                "type": 0,
                "difficulty": 5,
                "options": "Artificial Intelligence,Human Intelligence,Machine Learning,Robot Thinking",
                "parse": "人工智能的英文是 Artificial Intelligence。",
                "answer": "Artificial Intelligence"
              },
              // 多选题
              {
                "content": "以下哪些属于机器学习的常用算法？",
                "type": 1,
                "difficulty": 6,
                "options": "决策树,支持向量机,线性回归,冒泡排序",
                "parse": "前三项是机器学习算法，冒泡排序是排序算法。",
                "answer": "决策树,支持向量机,线性回归"
              },
              // 判断题
              {
                "content": "深度学习是机器学习的一个分支。",
                "type": 3,
                "difficulty": 4,
                "options": "正确,错误",
                "parse": "深度学习确实是机器学习的一个分支。",
                "answer": "正确"
              },
              // 填空题
              {
                "content": "人工智能的英文缩写是____。",
                "type": 2,
                "difficulty": 3,
                "options": "",
                "parse": "人工智能的英文缩写是 AI。",
                "answer": "AI"
              },
              // 简答题
              {
                "content": "请简述人工智能的主要应用领域。",
                "type": 4,
                "difficulty": 7,
                "options": "",
                "parse": "人工智能应用于医疗、金融、自动驾驶、智能家居等领域。",
                "answer": ""
              }
            ]

            注意事项：
            - type字段：0=单选题，1=多选题，2=填空题，3=判断题，4=简答题
            - options字段：单选/多选/判断为字符串（逗号分隔），填空/简答为""
            - answer字段：单选/多选为选项内容（如"Artificial Intelligence"或"决策树,支持向量机"），判断为"正确"/"错误"，填空/简答为文本或空
            - parse字段：所有题型都要有答案解析
            - 不要输出任何解释性文字，只输出JSON数组
             ，
             题型要求:
              1. 【单选题】(type=0): 
                - 必须是问句形式
                - options格式为"选项1,选项2,选项3,选项4"，逗号分隔，并且不要带有A. B. C. D. 等选项前缀
                - answer为选项内容字符串
              
              2. 【多选题】(type=1): 
                - 必须是问句形式
                - options格式为"选项1,选项2,选项3,选项4"，逗号分隔，并且不要带有A. B. C. D. 等选项前缀
                - answer为多个正确选项内容，用逗号连接
              
              3. 【填空题】(type=2):
                - 【重要】必须在题目内容中明确包含下划线"____"表示空白处，有几个答案就有几个下划线
                - 不能是问句形式，必须是陈述句中包含空白需要填写
                - answer为填入空白处的正确答案，有几个下划线就有几个答案用逗号隔开
              
              4. 【判断题】(type=3):
                - 必须是明确的陈述句，不能是问句
                - options固定为"正确,错误"
                - answer必须是"正确"或"错误"
                - 【严禁】不能包含下划线"____"或任何填空符号
              
              5. 【简答题】(type=4):
                - 必须是开放式问题
                - answer可以为空，但必须提供详细的parse(参考解析)
              重点：
                1. 单选题和多选题必须至少4个选项并且单选题只有一个答案，多选题有多个答案多个答案用逗号隔开，
                2. 判断题两个选项，填空题没有选项只有答案和解析它的多个答案用逗号隔开但是题目需要给足填空的下划线
                3. 简单题它是没有选项和答案的只有答案解析
              确保所有题目符合教育测试标准，内容准确，表述清晰，答案无歧义
              确保新题目与提供的参考资料内容高度相关,切记不要重复原题的知识点
            `;

        aiResult = await callSiliconAI(prompt, { bank: this.bank }, systemPrompt);
        aiText = typeof aiResult === 'string' ? aiResult.trim() : aiResult;
        // 去除AI返回的markdown代码块包裹
        if (typeof aiText === 'string') {
          aiText = aiText.replace(/```json|```/gi, '').trim();
        }
        let fixed = aiText;
        if (!fixed.startsWith('[')) fixed = '[' + fixed;
        if (!fixed.endsWith(']')) fixed = fixed + ']';
        questions = JSON.parse(fixed);
        if (!Array.isArray(questions)) questions = [questions];
      } catch (e) {
        console.error('AI生成失败:', e);
        this.$notify.error('AI生成失败，请重试');
        // 生成失败时也要重置状态
        setTimeout(() => {
          this.regeneratingIndex = -1;
        }, 500);
        return;
      }
      
      // 添加延迟，确保动画效果能够显示
      await new Promise(resolve => setTimeout(resolve, 1500));
      
      // 标准化新题目（和批量生成一致）
      const q = questions[0];
      let options = q.options;
      if (options === null || options === undefined) options = '';
      let optionsList = [];
      let correct_answer = q.answer || q.correct_answer || '';
      const typeMap = { 0: 'single', 1: 'multiple', 2: 'fillblank', 3: 'truefalse', 4: 'short_answer' };
      
      // 处理类型值，使用之前创建的mappedType
      let t = mappedType;
      if (typeof q.type === 'number') {
        t = typeMap[q.type] || mappedType;
      } else if (typeof q.type === 'string') {
        // 如果API返回的是中文题型，也需要转换
        t = typeZhToEnMap[q.type] || q.type || mappedType;
      }
      
      // 处理特殊类型映射，比如multiple_choice映射为multiple
      if (t === 'multiple_choice') {
        t = 'multiple';
      }
      
      const typeNum2 = typeof q.type === 'number' ? q.type : typeNumMap[t] || oldQuestion.typeNum || 1; // 提供默认值
      
      // 处理类型标签，确保一致性
      let typeLabel2 = typeZhMap[t] || '未知题型';
      if (typeLabel && typeLabel !== typeLabel2) {
        // 如果已有类型标签和新的不一致，优先使用已有的
        typeLabel2 = typeLabel;
      }
      
      let cleanContent = q.content || '';
      cleanContent = cleanContent.replace(/^判断[:：\s]*/i, '').replace(/^判断正误[:：\s]*/i, '');
      cleanContent = cleanContent.replace(/^(单选题|多选题|判断题|填空题|简答题|填空|简答)[:：\s]*/i, '');
      let optionsKV = [];
      if (typeLabel2 === '单选' || typeLabel2 === '多选' || typeLabel2 === '单选题' || typeLabel2 === '多选题') {
        // 处理选项数据，支持多种格式
        let arr = [];
        
        // 1. 处理数组格式的选项
        if (Array.isArray(options)) {
          arr = options.map(opt => {
            // 去除可能的选项前缀(如"A. ")
            if (typeof opt === 'string' && /^[A-Z]\.\s/.test(opt)) {
              return opt.replace(/^[A-Z]\.\s/, '').trim();
            }
            return opt;
          });
        } 
        // 2. 处理字符串格式的选项
        else if (typeof options === 'string') {
          arr = options.split(/[，,、\n]/).map(s => s.trim()).filter(Boolean);
        }
        
        // 生成选项键值对
        optionsKV = arr.map((text, idx) => ({ 
          key: String.fromCharCode(65 + idx), 
          value: text 
        }));
        
        // 处理正确答案
        if (correct_answer && optionsKV.length) {
          // 如果答案已经是字母(如"B")，不需要额外转换
          if (correct_answer.length === 1 && /^[A-Z]$/.test(correct_answer)) {
            // 答案已是正确格式
          } 
          // 否则尝试查找匹配的选项
          else {
            let ansArr = String(correct_answer).split(/[，,、]/).map(s => s.trim()).filter(Boolean);
            let letterArr = ansArr.map(ans => {
              // 查找选项中是否有匹配的值
              const found = optionsKV.find(opt => opt.value === ans);
              return found ? found.key : ans;
            }).filter(Boolean);
            correct_answer = letterArr.join(',');
          }
        }
      } else if (typeLabel2 === '判断' || typeLabel2 === '判断题') {
        // 处理判断题选项
        let arr = [];
        // 处理数组格式选项
        if (Array.isArray(options)) {
          arr = options.map(opt => {
            if (typeof opt === 'string' && /^[A-Z]\.\s/.test(opt)) {
              return opt.replace(/^[A-Z]\.\s/, '').trim();
            }
            return opt;
          });
        } else {
          arr = String(options || '').split(/[，,、\n]/).map(s => s.trim()).filter(Boolean);
        }
        
        if (arr.length < 2) arr = ['正确', '错误'];
        optionsKV = [
          { key: 'A', value: arr[0] || '正确' },
          { key: 'B', value: arr[1] || '错误' }
        ];
        
        // 处理判断题答案
        if (correct_answer) {
          if (correct_answer.includes('正确') || correct_answer.toLowerCase() === 'true') correct_answer = 'A';
          else if (correct_answer.includes('错误') || correct_answer.toLowerCase() === 'false') correct_answer = 'B';
          else if (correct_answer === 'A' || correct_answer === 'B') correct_answer = correct_answer;
          else correct_answer = '';
        }
      } else {
        // 填空题和简答题无选项
        optionsKV = [];
      }

      const newQ = {
        ...q,
        type: t,
        typeLabel: typeLabel2,
        typeNum: typeNum2,
        optionsKV,
        correct_answer,
        options: options || '',
        content: cleanContent,
        difficulty: q.difficulty ? parseInt(q.difficulty) || q.difficulty : 5, // 确保难度是数值
        difficultyLabel: this.getDifficultyLabelByNum(q.difficulty ? parseInt(q.difficulty) || q.difficulty : 5),
        difficultyColor: this.getDifficultyColorByNum(q.difficulty ? parseInt(q.difficulty) || q.difficulty : 5),
        // 确保题目类型信息完整
        typeColor: this.typeColors[t],
        // 添加题型图标映射，确保重新生成的题目展示正确的题型图标
        typeIcon: this.getTypeIcon(t),
        // 新增：保持和原始生成题目一致
        bankId: this.bank.bankId,
        generated: true
      };
      
      // 添加调试日志
      console.log('重新生成题目 - 类型映射:', {
        originalType: type,
        inputType: q.type, 
        mappedType: t,
        typeNum: typeNum2,
        typeLabel: typeLabel2,
        typeColor: this.typeColors[t],
        allTypeColors: this.typeColors,
        generatedQuestion: newQ
      });
      
      this.$set(this.previewQuestions, index, newQ);
      this.$notify({
        title: '题目已重新生成',
        message: '已为您生成新的题目',
        type: 'info'
      });
      
      // 重置重新生成状态
      this.regeneratingIndex = -1;
      
      // 在方法最后添加以下代码:
      console.group('===== 重新生成的题目信息 =====');
      console.log('题干:', newQ.content);
      console.log('类型:', newQ.typeLabel, `(${newQ.type}, typeNum: ${newQ.typeNum})`);
      console.log('选项KV映射:', newQ.optionsKV);
      console.log('正确答案:', newQ.correct_answer);
      console.log('完整题目对象:', newQ);
      console.groupEnd();
      
      // 如果只有一道题目，且重新生成了，视为已处理完所有原题目
      if (this.previewQuestions.length === 1) {
        this.generationCompleted = false;
      }
    },

    /**
     * 拒绝所有题目
     */
    rejectAllQuestions() {
      const count = this.previewQuestions.length;
      // 弹出确认框
      this.$confirm('确定要拒绝所有题目吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.previewQuestions = [];
        this.generationCompleted = false; // 重置状态，允许再次生成
        this.$notify({
          title: '弃用',
          message: `已拒绝${count}道题目`,
          type: 'success'
        });
      }).catch(() => {});
    },

    /**
     * 导出题目
     */
    exportQuestions() {
      this.$notify({
        title: '导出功能',
        message: '题目导出功能即将上线',
        type: 'info'
      });
    },

    /**
     * 保存选中的题目
     */
    saveSelectedQuestions() {
      const acceptedQuestions = this.previewQuestions.filter(q => q.accepted);
      if (acceptedQuestions.length > 0) {
        this.$emit('save-selected', acceptedQuestions);
        this.previewQuestions = this.previewQuestions.filter(q => !q.accepted);
      } else {
        this.$notify({
          title: '提示',
          message: '请先选择要保存的题目',
          type: 'warning'
        });
      }
    },

    /**
     * 移除关键词
     * @param {number} index - 要移除的关键词索引
     */
    removeKeyword(index) {
      const keywords = [...this.keywordTags];
      keywords.splice(index, 1);
      this.config.keywords = keywords.join(', ');
      this.$notify({
        title: '已移除关键词',
        message: '关键词已从列表中移除',
        type: 'info',
        duration: 2000
      });
    },
    isRecommendationSelected(option) {
      // 用 label 唯一标识
      return this.selectedRecommendations.some(sel => sel.label === option.label);
    },
    toggleRecommendation(option) {
      const idx = this.selectedRecommendations.findIndex(sel => sel.label === option.label);
      if (idx === -1) {
        this.selectedRecommendations.push(option);
      } else {
        this.selectedRecommendations.splice(idx, 1);
      }
      this.mergeSelectedRecommendations();
    },
    mergeSelectedRecommendations() {
      // 合并所有选中推荐配置的信息
      let mergedTypes = {};
      let mergedKeywords = [];
      let mergedDifficulty = null;
      let mergedStyle = null;
      
      // 先检查合并后的题目数是否会超过30题
      let totalCount = 0;
      this.selectedRecommendations.forEach(opt => {
        totalCount += Object.values(opt.types).reduce((sum, count) => sum + count, 0);
      });
      
      if (totalCount > 30) {
        this.$notify({
          title: '题目超限',
          message: '选中的推荐方案共包含' + totalCount + '道题，超过了30题上限，已自动调整',
          type: 'warning'
        });
        
        // 超过限制时，只保留最后选择的方案
        if (this.selectedRecommendations.length > 0) {
          const lastOption = this.selectedRecommendations[this.selectedRecommendations.length - 1];
          this.selectedRecommendations = [lastOption];
          
          // 重新计算总题目数
          totalCount = Object.values(lastOption.types).reduce((sum, count) => sum + count, 0);
          
          // 如果单个方案也超过30题，需要按比例缩减
          if (totalCount > 30) {
            const ratio = 30 / totalCount;
            Object.keys(lastOption.types).forEach(type => {
              lastOption.types[type] = Math.floor(lastOption.types[type] * ratio) || 1;
            });
          }
        }
      }
      
      // 继续正常合并流程
      this.selectedRecommendations.forEach(opt => {
        // 题型累加
        Object.entries(opt.types).forEach(([type, count]) => {
          mergedTypes[type] = (mergedTypes[type] || 0) + count;
        });
        // 关键词合并
        if (opt.keywords) {
          mergedKeywords = mergedKeywords.concat(opt.keywords.split(',').map(k => k.trim()));
        }
        // 难度/风格（第一个为主）
        if (!mergedDifficulty) mergedDifficulty = opt.difficulty;
        if (!mergedStyle) mergedStyle = opt.style;
      });
      
      // 确保题目总数不超过30
      const finalTotal = Object.values(mergedTypes).reduce((sum, count) => sum + count, 0);
      if (finalTotal > 30) {
        const ratio = 30 / finalTotal;
        Object.keys(mergedTypes).forEach(type => {
          mergedTypes[type] = Math.floor(mergedTypes[type] * ratio) || 1;
        });
      }
      
      // 去重关键词
      mergedKeywords = [...new Set(mergedKeywords)];
      // 更新配置
      this.config.questionTypes = mergedTypes;
      this.config.keywords = mergedKeywords.join(', ');
      this.config.difficulty = mergedDifficulty || 'medium';
      this.config.style = mergedStyle || 'exam';
    },
    // 新增：数字转题型名
    getTypeNameByNum(typeNum) {
      const map = {
        0: '单选',
        1: '多选',
        2: '填空',
        3: '判断',
        4: '简答'
      };
      return map[typeNum] || typeNum;
    },
    getTypeColorByNum(typeNum) {
      const map = {
        0: this.typeColors.single,
        1: this.typeColors.multiple,
        2: this.typeColors.fillblank,
        3: this.typeColors.truefalse,
        4: this.typeColors.short_answer
      };
      return map[typeNum] || '#888';
    },
    getDifficultyLabelByNum(diffNum) {
      // 处理字符串难度
      if (typeof diffNum === 'string') {
        // 如果是字符串类型的难度描述（如'easy'、'medium'、'hard'）直接映射
        const diffMap = {
          'easy': '简单',
          'medium': '中等',
          'hard': '困难'
        };
        if (diffMap[diffNum]) return diffMap[diffNum];
        
        // 尝试将字符串转为数字
        diffNum = parseInt(diffNum) || 5; // 默认中等
      }
      
      // 数值范围处理
      if (diffNum <= 3) return '简单';
      if (diffNum <= 7) return '中等';
      if (diffNum <= 10) return '困难';
      return '中等'; // 默认中等
    },
    
    getDifficultyColorByNum(diffNum) {
      // 处理字符串难度
      if (typeof diffNum === 'string') {
        // 如果是字符串类型的难度描述直接映射颜色
        const diffColorMap = {
          'easy': this.difficultyColors.easy,
          'medium': this.difficultyColors.medium,
          'hard': this.difficultyColors.hard
        };
        if (diffColorMap[diffNum]) return diffColorMap[diffNum];
        
        // 尝试将字符串转为数字
        diffNum = parseInt(diffNum) || 5; // 默认中等
      }
      
      // 数值范围处理
      if (diffNum <= 3) return this.difficultyColors.easy;
      if (diffNum <= 7) return this.difficultyColors.medium;
      if (diffNum <= 10) return this.difficultyColors.hard;
      return this.difficultyColors.medium; // 默认中等
    },
    // 添加获取题型图标的方法
    getTypeIcon(type) {
      const iconMap = {
        'single': 'fas fa-dot-circle',
        'multiple': 'fas fa-check-double',
        'truefalse': 'fas fa-balance-scale',
        'fillblank': 'fas fa-pencil-alt',
        'short_answer': 'fas fa-align-left'
      };
      return iconMap[type] || 'fas fa-question';
    },
    // 获取问题的类型颜色
    getQuestionTypeColor(question) {
      // 按优先级尝试不同的属性
      if (question.typeColor) {
        return question.typeColor;
      }
      
      if (question.typeNum !== undefined) {
        return this.getTypeColorByNum(question.typeNum);
      }
      
      if (question.type) {
        // 处理特殊类型映射
        let normalizedType = question.type;
        if (normalizedType === 'multiple_choice') {
          normalizedType = 'multiple';
        }
        return this.typeColors[normalizedType] || '#888888'; // 默认灰色
      }
      
      if (question.typeLabel) {
        const labelToType = {
          '单选': 'single',
          '多选': 'multiple',
          '判断': 'truefalse',
          '填空': 'fillblank',
          '简答': 'short_answer'
        };
        const mappedType = labelToType[question.typeLabel];
        if (mappedType) {
          return this.typeColors[mappedType] || '#888888';
        }
      }
      
      // 默认返回灰色
      return '#888888';
    },
    // 选项渲染优化
    getOptionList(q) {
      // 单选/多选
      if (q.typeLabel === '单选' || q.typeLabel === '多选') {
        let opts = q.options;
        // 1. null/undefined/空
        if (!opts) return [];
        // 2. JSON字符串
        if (typeof opts === 'string' && opts.trim().startsWith('[')) {
          try {
            const arr = JSON.parse(opts);
            opts = arr.map((opt, idx) => `${String.fromCharCode(65 + idx)}.${opt}`).join('\n');
          } catch (e) {
            // fallback
          }
        }
        // 3. 数组
        if (Array.isArray(opts)) {
          opts = opts.map((opt, idx) => `${String.fromCharCode(65 + idx)}.${opt}`).join('\n');
        }
        // 4. 标准A.选项字符串
        return opts.split('\n').map((opt, idx) => {
          const letter = String.fromCharCode(65 + idx);
          return { letter, key: letter, text: opt.substring(2), raw: opt };
        });
      }
      // 判断题
      if (q.typeLabel === '判断') {
        // 兼容数据库存储["正确","错误"]或A.正确\nB.错误
        let opts = q.options;
        if (!opts) return [
          { letter: 'A', key: 'A', text: '正确', raw: 'A.正确' },
          { letter: 'B', key: 'B', text: '错误', raw: 'B.错误' }
        ];
        if (typeof opts === 'string' && opts.trim().startsWith('[')) {
          try {
            const arr = JSON.parse(opts);
            return arr.map((txt, idx) => ({
              letter: String.fromCharCode(65 + idx),
              key: String.fromCharCode(65 + idx),
              text: txt,
              raw: `${String.fromCharCode(65 + idx)}.${txt}`
            }));
          } catch (e) {}
        }
        if (Array.isArray(opts)) {
          return opts.map((txt, idx) => ({
            letter: String.fromCharCode(65 + idx),
            key: String.fromCharCode(65 + idx),
            text: txt,
            raw: `${String.fromCharCode(65 + idx)}.${txt}`
          }));
        }
        // 标准A.正确\nB.错误
        return opts.split('\n').map((opt, idx) => {
          const letter = String.fromCharCode(65 + idx);
          return { letter, key: letter, text: opt.substring(2), raw: opt };
        });
      }
      // 填空题/简答题无选项
      return [];
    },

    /**
     * 处理从GenerateBankCard组件传来的直接生成请求
     * @param {Object} config - 生成配置
     */
    handleStartGenerate(config) {
      // 应用配置
      this.config.keywords = config.keywords;
      this.config.difficulty = config.difficulty;
      this.config.style = config.style;
      this.config.questionTypes = {...config.questionTypes};
      
      // 触发关键词分析处理
      this.analyzeKeywords();
      
      // 启动生成
      this.startGeneration();
    },

    // 添加刷新推荐方案的方法
    async refreshRecommendationsOnly() {
      if (!this.aiAnalysisResult || Object.keys(this.aiAnalysisResult).length === 0) {
        this.$notify({
          title: '无法刷新',
          message: '请先进行题库分析',
          type: 'warning'
        });
        return;
      }

      this.isAnalyzingRecommendations = true;
      
      try {
        const recommendations = await refreshRecommendations(this.aiAnalysisResult);
        if (recommendations && recommendations.length > 0) {
          this.recommendationOptions = recommendations;
          
          // 更新缓存
          const cache = window.__AI_BANK_ANALYSIS_CACHE__;
          const key = this.analysisCacheKey;
          if (cache[key]) {
            cache[key].recommendationOptions = recommendations;
          }
          
          this.$notify({
            title: '刷新成功',
            message: '智能推荐方案已更新',
            type: 'success'
          });
        } else {
          this.$notify({
            title: '刷新失败',
            message: '未能生成新的推荐方案',
            type: 'warning'
          });
        }
      } catch (error) {
        console.error('刷新推荐方案失败:', error);
        this.$notify.error('刷新推荐方案失败: ' + error.message);
      } finally {
        // 延迟关闭推荐方案分析状态，使效果更自然
        setTimeout(() => {
          this.isAnalyzingRecommendations = false;
        }, 800);
      }
    },

    /**
     * 处理分析完成事件
     * @param {Object} result - 分析结果
     */
    handleAnalysisCompleted(result) {
      // 直接使用子组件返回的分析结果
      this.aiAnalysisResult = result;
      this.suggestedKeywords = result.suggestedKeywords || [];
      
      // 使用API获取推荐方案
      this.refreshRecommendationsOnly();
      
      // 缓存结果
      const cache = window.__AI_BANK_ANALYSIS_CACHE__ || {};
      const key = this.analysisCacheKey;
      
      if (key) {
        cache[key] = {
          analysis: result,
          suggestedKeywords: this.suggestedKeywords,
          recommendationOptions: this.recommendationOptions
        };
        window.__AI_BANK_ANALYSIS_CACHE__ = cache;
      }
      
      // 设置其他UI状态
      this.knowledgeGap = result.missingKnowledgePoints && result.missingKnowledgePoints.length > 0;
    },

    /**
     * 打印生成的题目和选项映射（调试用）
     */
    printGeneratedQuestions() {
      console.group('===== 生成的题目及选项映射 =====');
      this.previewQuestions.forEach((q, idx) => {
        console.group(`题目 ${idx+1}: ${q.typeLabel}`);
        console.log('题干:', q.content);
        console.log('类型:', q.typeLabel, `(${q.type}, typeNum: ${q.typeNum})`);
        console.log('难度:', q.difficultyLabel);
        console.log('选项数组:', q.options);
        console.log('选项KV映射:', q.optionsKV);
        console.log('正确答案:', q.correct_answer);
        console.log('答案解析:', q.parse);
        console.log('完整题目对象:', q);
        console.groupEnd();
      });
      console.groupEnd();
    },
  },
  beforeDestroy() {
    // 组件销毁前清除定时器
    if (this.thinkingInterval) {
      clearInterval(this.thinkingInterval);
    }
  }
}

// 工具函数：解析选项为数组
function parseOptions(options) {
  if (Array.isArray(options)) return options;
  if (typeof options === 'string') {
    const str = options.trim();
    if (str.startsWith('[') && str.endsWith(']')) {
      try {
        return JSON.parse(str);
      } catch {
        // fallback
      }
    }
    // 普通字符串分割
    return str.split(/[,，、\n]/).map(s => s.trim()).filter(Boolean);
  }
  return [];
}
</script>



<style lang="less" scoped>
// 颜色变量 - 更新为更现代的色调
@primary: #4361EE;
@primary-light: #5E72E4;
@primary-lighter: #8A9EFF;
@primary-dark: #3A0CA3;
@secondary: #7209B7;
@secondary-dark: #7209b7; // 深紫色
@success: #10B981;
@warning: #F59E0B;
@danger: #EF4444;
@info: #3B82F6;
@purple: #8B5CF6;
@gray-50: #F9FAFB;
@gray-100: #F3F4F6;
@gray-200: #E5E7EB;
@gray-300: #D1D5DB;
@gray-400: #9CA3AF;
@gray-500: #6B7280;
@gray-600: #4B5563;
@gray-700: #374151;
@gray-800: #1F2937;
@gray-900: #111827;

// 新增颜色 - 更柔和的文本颜色
@text-success: #047857;
@text-warning: #B45309;
@text-danger: #B91C1C;
@text-info: #1D4ED8;

// 阴影 - 更柔和的阴影效果
@shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.05);
@shadow-md: 0 4px 6px rgba(0, 0, 0, 0.08);
@shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.08);
@shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.08);
@shadow-2xl: 0 25px 50px rgba(0, 0, 0, 0.1);
@shadow-inner: inset 0 2px 4px rgba(0, 0, 0, 0.03);
// 阴影变量
@shadow-xs: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
@shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
@shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
@shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);

// 圆角 - 更现代的圆角
@radius-sm: 6px;
@radius-md: 8px;
@radius-lg: 12px;
@radius-xl: 16px;
@radius-2xl: 20px;
@radius-3xl: 24px;
@radius-full: 9999px;

// 过渡 - 更流畅的动画
@transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
@transition-slow: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
@transition-fast: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);

// 动画 - 新增更多动画效果
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes dialogEnter {
  from {
    opacity: 0;
    transform: translateY(20px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes pulse {
  0% { transform: scale(1); opacity: 1; }
  70% { transform: scale(1.1); opacity: 0.7; }
  100% { transform: scale(1.2); opacity: 0; }
}

@keyframes float {
  0% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
  100% { transform: translateY(0); }
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@keyframes shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

@keyframes glow {
  0% { opacity: 0.3; transform: scale(0.8); }
  50% { opacity: 1; transform: scale(1.2); }
  100% { opacity: 0.3; transform: scale(0.8); }
}

// 主容器样式
.ai-generator-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 2000;
  animation: fadeIn 0.3s ease-out;
  backdrop-filter: blur(10px);
}

.ai-generator-container {
  background: white;
  border-radius: @radius-3xl;
  width: 90%;
  max-width: 1400px;
  height: 85vh;
  box-shadow: @shadow-2xl;
  display: flex;
  flex-direction: column;
  animation: dialogEnter 0.3s ease-out;
  overflow: hidden;
  position: relative;
  border: 1px solid rgba(255, 255, 255, 0.2);
  transform-origin: center center;

  &.fullscreen {
    width: 100%;
    height: 100vh;
    max-width: none;
    border-radius: 0;
  }

  // 页脚样式
  .ai-generator-footer {
    padding: 1rem 1.5rem;
    border-top: 1px solid @gray-200;
    background: white;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 1rem;
    position: sticky;
    bottom: 0;
    z-index: 10;
    box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);

    button {
      padding: 0.625rem 1.25rem;
      border-radius: @radius-md;
      font-size: 0.875rem;
      font-weight: 600;
      cursor: pointer;
      transition: @transition;
      display: flex;
      align-items: center;
      gap: 0.5rem;
      border: 1px solid transparent;
      letter-spacing: 0.3px;

      i {
        font-size: 0.8rem;
        transition: @transition;
      }

      &:disabled {
        opacity: 0.7;
        cursor: not-allowed;
      }
    }

    .btn-cancel {
      background-color: transparent;
      color: @gray-500;
      border: 2px solid @gray-300;
      border-radius: @radius-md;
      padding: 0.6rem 1.2rem;
      font-size: 0.875rem;
      font-weight: 500;
      cursor: pointer;
      transition: all 0.25s;
      
      &:hover {
        background-color: @gray-100;
        color: @gray-700;
        border-color: @gray-400;
        transform: translateY(-1px);
        box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1);
      }
      
      i {
        margin-right: 0.3rem;
        color: @danger;
      }
    }

    .btn-generate {
      background: linear-gradient(135deg, @primary, @secondary);
      color: white;
      box-shadow: @shadow-md;
      position: relative;
      overflow: hidden;

      &::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: linear-gradient(135deg, rgba(255,255,255,0.1), rgba(255,255,255,0.2));
        opacity: 0;
        transition: @transition;
      }

      &:hover:not(:disabled) {
        background: linear-gradient(135deg, darken(@primary, 5%), darken(@secondary, 5%));
        transform: translateY(-2px);
        box-shadow: @shadow-lg;

        &::after {
          opacity: 1;
        }
      }

      &:active:not(:disabled) {
        transform: translateY(0);
        box-shadow: @shadow-md;
      }

      &:disabled {
        background: linear-gradient(135deg, lighten(@primary, 20%), lighten(@secondary, 20%));
      }
    }

    .btn-reject {
      background: @danger;
      color: white;
      box-shadow: @shadow-md;
      position: relative;
      overflow: hidden;
      border: 1px solid transparent;
      &:hover {
        background: darken(@danger, 5%);
        transform: translateY(-2px);
        box-shadow: @shadow-lg;
      }
      &:active {
        transform: translateY(0);
        box-shadow: @shadow-md;
      }
    }

    .btn-save {
      background: @success;
      color: white;
      box-shadow: @shadow-md;
      position: relative;
      overflow: hidden;

      &::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: linear-gradient(135deg, rgba(255,255,255,0.1), rgba(255,255,255,0.2));
        opacity: 0;
        transition: @transition;
      }

      &:hover {
        background: darken(@success, 5%);
        transform: translateY(-2px);
        box-shadow: @shadow-lg;

        &::after {
          opacity: 1;
        }
      }

      &:active {
        transform: translateY(0);
        box-shadow: @shadow-md;
      }
    }
  }

  // 响应式调整
  @media (max-width: 768px) {
    .ai-generator-footer {
      padding: 0.75rem 1rem;
      flex-wrap: wrap;
      justify-content: center;

      button {
        flex: 1;
        justify-content: center;
        padding: 0.5rem;
        font-size: 0.8125rem;
      }
    }
  }

  @media (max-width: 480px) {
    .ai-generator-footer {
      gap: 0.5rem;

      button {
        min-width: 100px;
      }
    }
  }
}

// 头部样式
.ai-generator-header {
  padding: 1rem 1.5rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: linear-gradient(135deg, @primary, @secondary);
  color: white;
  position: relative;
  z-index: 10;
  box-shadow: @shadow-md;

  .header-left {
    display: flex;
    align-items: center;
    gap: 1rem;

    h2 {
      margin: 0;
      font-size: 1.25rem;
      font-weight: 600;
      display: flex;
      align-items: center;
      gap: 0.5rem;
      letter-spacing: 0.5px;
      text-shadow: 0 1px 2px rgba(0,0,0,0.1);

      i {
        font-size: 1.2em;
      }
    }

    .ai-status {
      display: flex;
      align-items: center;
      gap: 0.5rem;
      font-size: 0.875rem;
      opacity: 0.9;
      background: rgba(255, 255, 255, 0.1);
      padding: 0.25rem 0.75rem;
      border-radius: @radius-full;
      backdrop-filter: blur(5px);
      transition: @transition;

      &:hover {
        background: rgba(255, 255, 255, 0.15);
      }

      .pulse-dot {
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background-color: @success;
        animation: pulse 1.5s infinite;
        box-shadow: 0 0 0 2px rgba(@success, 0.3);
      }
    }
  }

  .header-actions {
    display: flex;
    gap: 0.5rem;

    .btn-icon {
      background: rgba(255, 255,255, 0.1);
      border: none;
      width: 36px;
      height: 36px;
      border-radius: 50%;
      color: white;
      cursor: pointer;
      transition: @transition;
      display: flex;
      align-items: center;
      justify-content: center;
      backdrop-filter: blur(5px);
      position: relative;

      &:hover {
        background: rgba(255, 255, 255, 0.2);
        transform: scale(1.1);
      }

      &.btn-close:hover {
        background: rgba(@danger, 0.7);
      }

      i {
        font-size: 1rem;
      }

      .tooltip {
        position: absolute;
        bottom: -30px;
        left: 50%;
        transform: translateX(-50%);
        background: @gray-800;
        color: white;
        padding: 0.25rem 0.5rem;
        border-radius: @radius-sm;
        font-size: 0.75rem;
        opacity: 0;
        pointer-events: none;
        transition: @transition;
        white-space: nowrap;
      }

      &:hover .tooltip {
        opacity: 1;
        bottom: -35px;
      }
    }
  }
}

// 内容区域
.ai-generator-content {
  display: flex;
  flex: 1;
  overflow: hidden;
  position: relative;
}

// 左侧面板
.left-panel {
  width: 380px;
  padding: 1.5rem;
  border-right: 1px solid @gray-200;
  background: white;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  scrollbar-width: thin;
  scrollbar-color: @primary-light @gray-100;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-track {
    background: @gray-100;
    border-radius: @radius-full;
  }

  &::-webkit-scrollbar-thumb {
    background-color: @primary-light;
    border-radius: @radius-full;
    transition: @transition;

    &:hover {
      background-color: darken(@primary-light, 10%);
    }
  }
}

// 配置区域
.config-section {
  background: white;
  border-radius: @radius-xl;
  box-shadow: @shadow-sm;
  border: 1px solid @gray-200;
  padding: 1.25rem;
  transition: @transition;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;

  &:hover {
    box-shadow: @shadow-md;
  }

  .section-header {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.5rem;

    i {
      color: @primary;
      font-size: 1.1rem;
    }

    h3 {
      margin: 0;
      font-size: 1rem;
      color: @gray-800;
      font-weight: 600;
    }

    .ai-tag {
      margin-left: auto;
      background: rgba(@primary, 0.1);
      color: @primary;
      padding: 0.25rem 0.75rem;
      border-radius: @radius-full;
      font-size: 0.75rem;
      display: flex;
      align-items: center;
      gap: 0.25rem;
      transition: @transition;

      &:hover {
        background: rgba(@primary, 0.2);
      }

      i {
        font-size: 0.7rem;
        color: @primary;
      }
    }
  }
}

// 配置组
.config-group {
  label {
    display: flex;
    align-items: center;
    margin-bottom: 0.5rem;
    font-size: 0.875rem;
    font-weight: 500;
    color: @gray-700;
    gap: 0.5rem;

    .ai-suggestion-badge {
      background: rgba(@info, 0.1);
      color: @info;
      padding: 0.125rem 0.5rem;
      border-radius: @radius-full;
      font-size: 0.6875rem;
      font-weight: 500;
      transition: @transition;

      &:hover {
        background: rgba(@info, 0.2);
      }
    }
  }
}

// 输入框容器
.keyword-input-container {
  position: relative;
  margin-bottom: 1rem;

  .ai-feedback {
    margin-top: 0.5rem;
    font-size: 0.75rem;
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.25rem 0.5rem;
    border-radius: @radius-sm;
    transition: @transition;

    i {
      font-size: 0.7rem;
    }

    &.positive {
      color: @text-success;
      background: rgba(@success, 0.1);

      &:hover {
        background: rgba(@success, 0.2);
      }
    }

    &.neutral {
      color: @text-info;
      background: rgba(@info, 0.1);

      &:hover {
        background: rgba(@info, 0.2);
      }
    }

    &.warning {
      color: @text-warning;
      background: rgba(@warning, 0.1);

      &:hover {
        background: rgba(@warning, 0.2);
      }
    }
  }
}

// 带图标的输入框
.input-with-icon {
  position: relative;

  i {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: @gray-500;
    font-size: 0.875rem;
    transition: @transition;
  }

  .btn-smart-suggest {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: rgba(@primary, 0.1);
    border: none;
    color: @primary;
    cursor: pointer;
    transition: @transition;
    display: flex;
    align-items: center;
    justify-content: center;

    &:hover {
      background: rgba(@primary, 0.2);
      transform: translateY(-50%) scale(1.1);
    }
    
    &:active {
      background: rgba(@primary, 0.3);
      transform: translateY(-50%) scale(0.95);
    }
    
    &.loading {
      animation: rotate 1s linear infinite;
    }

    i {
      position: static;
      transform: none;
      font-size: 0.8rem;
    }
  }
}

@keyframes rotate {
  from { transform: translateY(-50%) rotate(0deg); }
  to { transform: translateY(-50%) rotate(360deg); }
}

// 现代输入框
.modern-input {
  width: 100%;
  padding: 0.75rem 3rem 0.75rem 2.5rem;
  border: 1px solid @gray-300;
  border-radius: @radius-md;
  font-size: 0.875rem;
  transition: @transition;
  background-color: @gray-50;
  font-family: inherit;
  box-shadow: @shadow-inner;

  &:focus {
    outline: none;
    border-color: @primary;
    box-shadow: 0 0 0 3px rgba(@primary, 0.1);
    background-color: white;

    ~ i {
      color: @primary;
    }
  }

  &::placeholder {
    color: @gray-400;
  }
}

// AI建议区域
.ai-suggestions {
  margin-top: 1rem;
  background: @gray-50;
  border-radius: @radius-md;
  padding: 0.75rem;
  border: 1px dashed @gray-300;
  transition: @transition;

  &:hover {
    border-color: @primary-light;
    box-shadow: @shadow-sm;
  }

  .suggestion-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
    font-size: 0.8125rem;
    color: @gray-700;
    position: relative;

    i {
      color: @info;
    }

    .btn-refresh {
      margin-left: auto;
      width: 24px;
      height: 24px;
      border-radius: 50%;
      background: rgba(@info, 0.1);
      border: none;
      color: @info;
      cursor: pointer;
      transition: all 0.3s cubic-bezier(0.19, 1, 0.22, 1);
      display: flex;
      align-items: center;
      justify-content: center;
      overflow: hidden;
      position: relative;

      &:after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: radial-gradient(circle, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0) 70%);
        opacity: 0;
        transform: scale(0);
        transition: all 0.5s;
      }

      &:hover {
        background: rgba(@info, 0.2);
        transform: rotate(180deg);
        
        &:after {
          opacity: 0.5;
          transform: scale(2);
        }
      }

      &:disabled {
        opacity: 0.6;
        cursor: not-allowed;
      }

      &.refreshing i {
        animation: spin 1s linear infinite;
      }

      i {
        font-size: 0.7rem;
        color: inherit;
        transition: transform 0.3s;
      }
    }
  }

  .suggestion-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    transition: opacity 0.3s;
    
    &.is-refreshing {
      pointer-events: none;
      position: relative;
      
      &::after {
        content: '';
        position: absolute;
        inset: -5px;
        background: radial-gradient(circle, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0) 70%);
        border-radius: 10px;
        opacity: 0;
        animation: pulseBg 2s ease infinite;
      }
    }

    .tag {
      background: @primary-lighter;
      color: @primary;
      padding: 0.25rem 0.75rem;
      border-radius: @radius-full;
      font-size: 0.75rem;
      cursor: pointer;
      transition: all 0.3s cubic-bezier(0.19, 1, 0.22, 1);
      display: flex;
      align-items: center;
      gap: 0.25rem;
      border: 1px solid rgba(@primary, 0.2);
      position: relative;
      overflow: hidden;
      
      i {
        font-size: 0.6rem;
        transition: all 0.3s;
      }
      
      &.refreshing {
        background: rgba(@primary-lighter, 0.7);
        box-shadow: 0 0 0 1px rgba(@primary, 0.3);
        transform: scale(0.98);
        animation: pulseTag 1.5s ease-in-out infinite alternate;
        
        i.fa-spinner {
          font-size: 0.7rem;
          color: @primary;
          margin-left: 2px;
        }
      }
      
      &:after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: radial-gradient(circle, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0) 70%);
        opacity: 0;
        transform: scale(0);
        transition: all 0.5s;
      }
      
      &:hover:not(.refreshing) {
        background: @primary;
        color: white;
        transform: translateY(-2px);
        box-shadow: @shadow-sm;
        
        &:after {
          opacity: 0.5;
          transform: scale(2);
        }

        i {
          color: white;
        }
      }
    }
  }
}

@keyframes pulseTag {
  0% {
    opacity: 0.8;
    box-shadow: 0 0 0 0 rgba(@primary, 0.5);
  }
  100% {
    opacity: 1;
    box-shadow: 0 0 0 4px rgba(@primary, 0);
  }
}

@keyframes pulseBg {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 0.15;
  }
  100% {
    opacity: 0;
  }
}

// 配置网格
.config-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 1rem;
}

// 配置项
.config-item {
  label {
    display: block;
    margin-bottom: 0.5rem;
    font-size: 0.8125rem;
    font-weight: 500;
    color: @gray-700;
  }
}

// 类型配置区域
.type-config-section {
  .section-header {
    position: relative;

    .total-count {
      position: absolute;
      right: 0;
      font-size: 0.8125rem;
      color: @gray-600;

      .highlight {
        font-weight: 600;
        color: @primary;
      }
    }
  }
}

// 类型配置网格
.type-config-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 0.75rem;
}

// 类型配置卡片
.type-config-card {
  display: flex;
  align-items: center;
  padding: 0.75rem;
  border-radius: @radius-md;
  border: 1px solid @gray-200;
  cursor: pointer;
  transition: @transition;
  gap: 0.75rem;
  background-color: white;
  position: relative;
  overflow: hidden;

  &:hover {
    border-color: @primary-light;
    box-shadow: @shadow-sm;
    transform: translateY(-2px);
  }

  &.active {
    border-color: @primary;
    background-color: rgba(@primary, 0.05);
    box-shadow: 0 0 0 1px @primary;

    .type-icon {
      color: white;
    }
  }

  .type-icon {
    width: 36px;
    height: 36px;
    border-radius: @radius-md;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 0.9rem;
    flex-shrink: 0;
    transition: @transition;
    box-shadow: @shadow-sm;
  }

  .type-info {
    flex: 1;
    min-width: 0;

    .type-name {
      display: block;
      font-weight: 500;
      color: @gray-800;
      font-size: 0.8125rem;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .type-desc {
      display: block;
      font-size: 0.6875rem;
      color: @gray-500;
      margin-top: 0.125rem;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  }

  .type-count {
    display: flex;
    align-items: center;
    gap: 0.25rem;

    .count-btn {
      width: 22px;
      height: 22px;
      border-radius: 4px;
      border: 1px solid @gray-300;
      background: white;
      color: @gray-700;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: @transition;

      &:hover {
        background: @gray-100;
        color: @primary;
      }

      i {
        font-size: 0.5rem;
      }
    }

    .count-value {
      font-size: 0.75rem;
      font-weight: 500;
      color: @gray-800;
      min-width: 16px;
      text-align: center;
    }
  }
}

// AI推荐区域
.ai-recommendations {
  .header-actions {
    margin-left: auto;
    display: flex;
    gap: 0.5rem;
    align-items: center;
  }

  .btn-refresh-recommendations {
    background: rgba(@info, 0.1);
    border: none;
    padding: 0.25rem 0.75rem;
    border-radius: @radius-full;
    font-size: 0.75rem;
    color: @info;
    cursor: pointer;
    transition: @transition;
    display: flex;
    align-items: center;
    gap: 0.25rem;

    &:hover:not(:disabled) {
      background: rgba(@info, 0.2);
      transform: translateY(-1px);
    }

    &:disabled {
      opacity: 0.6;
      cursor: not-allowed;
    }

    i {
      font-size: 0.7rem;
    }
  }

  .btn-smart-analyze {
    background: rgba(@primary, 0.1);
    border: none;
    padding: 0.25rem 0.75rem;
    border-radius: @radius-full;
    font-size: 0.75rem;
    color: @primary;
    cursor: pointer;
    transition: @transition;
    display: flex;
    align-items: center;
    gap: 0.25rem;

    &:hover {
      background: rgba(@primary, 0.2);
      transform: translateY(-1px);
    }

    i {
      font-size: 0.7rem;
    }
  }

  .recommendation-options {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 0.75rem;
  }

  .recommendation-card {
    background: white;
    border: 1px solid @gray-200;
    border-radius: @radius-md;
    padding: 0.75rem;
    cursor: pointer;
    transition: @transition;
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
    position: relative;
    overflow: hidden;

    &:hover {
      transform: translateY(-3px);
      box-shadow: @shadow-sm;
      border-color: @primary-light;
    }

    &::after {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: linear-gradient(135deg, rgba(255,255,255,0), rgba(255,255,255,0.8));
      opacity: 0;
      transition: @transition;
    }

    &:hover::after {
      opacity: 1;
    }

    .recommendation-icon {
      width: 32px;
      height: 32px;
      border-radius: @radius-md;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-size: 0.9rem;
      flex-shrink: 0;
      box-shadow: @shadow-sm;
    }

    .recommendation-content {
      flex: 1;
      min-width: 0;

      h4 {
        margin: 0 0 0.25rem 0;
        font-size: 0.8125rem;
        color: @gray-800;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }

      .recommendation-stats {
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem;
        margin-bottom: 0.5rem;

        .stat-item {
          font-size: 0.6875rem;
          color: @gray-600;
          display: flex;
          align-items: center;
          gap: 0.25rem;

          i {
            font-size: 0.6rem;
          }
        }
      }

      .type-tags {
        display: flex;
        flex-wrap: wrap;
        gap: 0.25rem;

        .type-tag {
          font-size: 0.625rem;
          padding: 0.125rem 0.5rem;
          border-radius: 10px;
          background: @gray-100;
          color: @gray-700;
          transition: @transition;

          &:hover {
            background: @gray-200;
          }
        }
      }
    }
  }
}

// 结果面板
.result-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden; /* 防止内容溢出 */
}

// 结果头部
.result-header {
  padding: 1rem 1.5rem;
  border-bottom: 1px solid @gray-200;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: white;
  position: sticky;
  top: 0;
  z-index: 5;
  box-shadow: @shadow-sm;

  h3 {
    margin: 0;
    font-size: 1rem;
    color: @gray-700;
    display: flex;
    align-items: center;
    gap: 0.5rem;

    i {
      color: @primary;
    }
  }

  .result-stats {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    align-items: center;

    .stat-item {
      display: flex;
      align-items: center;
      gap: 0.5rem;
    }

    .stat-badge {
      font-size: 0.75rem;
      padding: 0.25rem 0.5rem;
      border-radius: 0.5rem;
      color: white;
      font-weight: 500;
      box-shadow: @shadow-sm;
    }

    .stat-count {
      font-size: 0.75rem;
      color: @gray-600;
    }
  }

  .ai-actions {
    display: flex;
    margin-left: auto;

    .btn-ai-optimize {
      background: rgba(@primary, 0.1);
      border: none;
      padding: 0.375rem 0.75rem;
      border-radius: @radius-full;
      font-size: 0.75rem;
      color: @primary;
      cursor: pointer;
      transition: @transition;
      display: flex;
      align-items: center;
      gap: 0.25rem;
      font-weight: 500;

      &:hover {
        background: rgba(@primary, 0.2);
        transform: translateY(-1px);
      }

      i {
        font-size: 0.8rem;
      }
    }
  }
}

// 结果内容区域
.result-content {
  flex: 1;
  overflow-y: auto; /* 添加纵向滚动 */
  padding: 1.5rem;
  position: relative;
  background: @gray-50;
  padding-bottom: 20px; /* 确保底部有足够空间 */
  scrollbar-width: thin;
  scrollbar-color: @primary-light @gray-100;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-track {
    background: @gray-100;
    border-radius: @radius-full;
  }

  &::-webkit-scrollbar-thumb {
    background-color: @primary-light;
    border-radius: @radius-full;
    transition: @transition;

    &:hover {
      background-color: darken(@primary-light, 10%);
    }
  }
}

/* 生成状态样式 */
.generating-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 2rem;
  height: 100%;
  width: 100%;

  .ai-thinking-animation {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    margin-bottom: 2rem;

    .ai-avatar {
      width: 60px;
      height: 60px;
      border-radius: 50%;
      background: linear-gradient(135deg, @primary, @secondary);
      color: white;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 1.5rem;
      box-shadow: @shadow-md;
      animation: float 3s ease-in-out infinite;
      position: relative;

      &::after {
        content: '';
        position: absolute;
        top: -5px;
        left: -5px;
        right: -5px;
        bottom: -5px;
        border-radius: 50%;
        border: 2px solid rgba(@primary, 0.3);
        animation: pulse 2s infinite;
      }
    }

    .thinking-bubbles {
      display: flex;
      flex-direction: column;
      gap: 0.5rem;
      align-items: flex-start;

      .bubble {
        background: white;
        padding: 0.75rem 1rem;
        border-radius: 1rem 1rem 1rem 0;
        font-size: 0.875rem;
        color: @gray-700;
        box-shadow: @shadow-sm;
        opacity: 0.5;
        transform: translateY(5px);
        transition: all 0.3s ease;
        position: relative;

        &::before {
          content: '';
          position: absolute;
          left: -8px;
          bottom: 0;
          width: 0;
          height: 0;
          border-right: 8px solid white;
          border-top: 8px solid transparent;
          border-bottom: 8px solid transparent;
          filter: drop-shadow(-2px 0 2px rgba(0,0,0,0.1));
        }

        &.active {
          opacity: 1;
          transform: translateY(0);
          background: @primary;
          color: white;

          &::before {
            border-right-color: @primary;
          }
        }
      }
    }
  }

  .progress-container {
    width: 100%;
    max-width: 500px;

    .progress-info {
      display: flex;
      justify-content: space-between;
      margin-bottom: 0.5rem;
      font-size: 0.875rem;
      color: @gray-600;
    }

    .progress-bar {
      height: 8px;
      background: @gray-200;
      border-radius: 4px;
      overflow: hidden;
      box-shadow: @shadow-inner;
    }

    .progress-fill {
      height: 100%;
      background: linear-gradient(90deg, @primary, @secondary);
      border-radius: 4px;
      transition: width 0.5s ease;
      position: relative;
      overflow: hidden;

      &::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: linear-gradient(90deg,
        rgba(255,255,255,0.1) 25%,
        rgba(255,255,255,0.3) 50%,
        rgba(255,255,255,0.1) 75%);
        background-size: 200% 100%;
        animation: shimmer 2s infinite linear;
      }
    }
  }

  .generation-preview {
    width: 100%;
    margin-top: 2rem;
    text-align: left;
    background: white;
    border-radius: @radius-lg;
    padding: 1rem;
    box-shadow: @shadow-sm;

    h5 {
      font-size: 0.875rem;
      color: @gray-600;
      margin: 0 0 1rem 0;
      padding-bottom: 0.5rem;
      border-bottom: 1px solid @gray-200;
    }

    .preview-scroll {
      max-height: 150px;
      overflow-y: auto;
      padding-right: 0.5rem;

      .preview-item {
        background: @gray-50;
        padding: 0.75rem;
        border-radius: @radius-md;
        margin-bottom: 0.75rem;
        display: flex;
        align-items: center;
        gap: 0.5rem;
        transition: @transition;

        &:hover {
          background: @gray-100;
          transform: translateX(5px);
        }

        .preview-type {
          font-size: 0.625rem;
          padding: 0.125rem 0.5rem;
          border-radius: 10px;
          color: white;
          font-weight: 500;
          flex-shrink: 0;
        }

        .preview-content {
          font-size: 0.8125rem;
          color: @gray-700;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }
      }
    }
  }
}

/* 错误消息样式 */
.error-message {
  background: rgba(@danger, 0.1);
  color: @danger;
  padding: 1rem;
  border-radius: @radius-lg;
  margin-bottom: 1.5rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
  position: relative;
  border-left: 4px solid @danger;
  animation: fadeIn 0.3s ease-out;

  i {
    font-size: 1rem;
  }

  .retry-btn {
    margin-left: auto;
    background: rgba(@danger, 0.2);
    border: none;
    padding: 0.25rem 0.75rem;
    border-radius: @radius-md;
    font-size: 0.75rem;
    color: @danger;
    cursor: pointer;
    transition: @transition;
    display: flex;
    align-items: center;
    gap: 0.25rem;

    &:hover {
      background: rgba(@danger, 0.3);
      transform: translateY(-1px);
    }

    i {
      font-size: 0.7rem;
    }
  }
}

/* 题目预览区域 */
.questions-preview {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;

  /* 题目卡片样式优化 */
  .question-card {
    background: white;
    border-radius: @radius-lg;
    box-shadow: @shadow-md;
    overflow: hidden;
    transition: all 0.3s ease;
    position: relative;
    border-top: 4px solid transparent;
    animation: fadeInUp 0.3s ease-out;

    &:hover {
      transform: translateY(-3px);
      box-shadow: @shadow-lg;
    }

    /* 题目类型颜色标识 */
    &.single {
      border-top-color: #4361EE;
      .question-type { background: linear-gradient(135deg, #4361EE, #3A0CA3); }
    }
    &.multiple {
      border-top-color: #3A0CA3;
      .question-type { background: linear-gradient(135deg, #3A0CA3, #7209B7); }
    }
    &.truefalse {
      border-top-color: #10B981;
      .question-type { background: linear-gradient(135deg, #10B981, #059669); }
    }
    &.fillblank {
      border-top-color: #F59E0B;
      .question-type { background: linear-gradient(135deg, #F59E0B, #D97706); }
    }
    &.short_answer {
      border-top-color: #8B5CF6;
      .question-type { background: linear-gradient(135deg, #8B5CF6, #7C3AED); }
    }

    /* 题目头部 */
    .question-header {
      padding: 0.75rem 1rem;
      display: flex;
      align-items: center;
      gap: 0.75rem;
      flex-wrap: wrap;
      background: fade(@gray-100, 50%);
      border-bottom: 1px solid @gray-200;

      .question-type {
        font-size: 0.75rem;
        padding: 0.25rem 0.75rem;
        border-radius: @radius-full;
        color: white;
        font-weight: 600;
        display: flex;
        align-items: center;
        gap: 0.25rem;
        box-shadow: @shadow-sm;

        i {
          font-size: 0.7rem;
        }
      }

      .question-difficulty {
        font-size: 0.75rem;
        padding: 0.25rem 0.75rem;
        border-radius: @radius-full;
        font-weight: 500;
        background: @gray-200;
        color: @gray-700;
        display: flex;
        align-items: center;
        gap: 0.25rem;

        i {
          font-size: 0.7rem;
        }
      }

      .question-actions {
        margin-left: auto;
        display: flex;
        gap: 0.5rem;

        .btn-action {
          padding: 0.375rem 0.75rem;
          border-radius: @radius-md;
          font-size: 0.8125rem;
          font-weight: 500;
          border: none;
          cursor: pointer;
          transition: all 0.2s ease;
          display: flex;
          align-items: center;
          gap: 0.375rem;
          box-shadow: @shadow-sm;

          i {
            font-size: 0.75rem;
          }

          &.btn-accept {
            background: @success;
            color: white;

            &:hover {
              background: darken(@success, 5%);
              transform: translateY(-1px);
            }
          }

          &.btn-reject {
            background: @danger;
            color: white;

            &:hover {
              background: darken(@danger, 5%);
              transform: translateY(-1px);
            }
          }

          &.btn-regenerate {
            background: @info;
            color: white;

            &:hover {
              background: darken(@info, 5%);
              transform: translateY(-1px);
            }
          }
        }
      }
    }

    /* 题目内容 */
    .question-content {
      padding: 1.25rem 1.5rem;
      font-size: 0.9375rem;
      color: @gray-800;
      line-height: 1.6;
      position: relative;

      &:before {
        content: "Q";
        position: absolute;
        left: 0.5rem;
        top: 1rem;
        font-size: 2.5rem;
        font-weight: bold;
        color: fade(@gray-300, 50%);
        z-index: 0;
      }

      > * {
        position: relative;
        z-index: 1;
      }
    }

    /* 选项区域 */
    .question-options {
      padding: 0 1.5rem 1rem;

      .option-item {
        display: flex;
        align-items: center;
        gap: 0.75rem;
        padding: 0.75rem;
        margin-bottom: 0.5rem;
        border-radius: @radius-md;
        background: @gray-50;
        font-size: 0.875rem;
        transition: all 0.2s ease;
        position: relative;

        .option-letter {
          font-weight: 600;
          color: @gray-700;
        }

        .option-text {
          flex: 1;
        }

        &.correct {
          background-color: rgba(67, 97, 238, 0.1);
          border: 1px solid rgba(67, 97, 238, 0.3);
          
          .option-letter {
            color: #4361EE;
            font-weight: bold;
          }
        }
      }
    }

    /* 题目底部 */
    .question-footer {
      padding: 1rem 1.5rem;
      background: @gray-50;
      border-top: 1px solid @gray-200;

      .answer-section {
        margin-bottom: 0.75rem;

        .answer-label {
          font-size: 0.8125rem;
          color: @gray-600;
          font-weight: 500;
          display: flex;
          align-items: center;
          gap: 0.25rem;

          &:before {
            content: "";
            display: inline-block;
            width: 1rem;
            height: 1rem;
            background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310B981'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z'/%3E%3C/svg%3E") no-repeat center;
            opacity: 0.8;
          }
        }

        .answer-value {
          display: block;
          margin-top: 0.25rem;
          padding: 0.5rem;
          background: white;
          border-radius: @radius-md;
          font-size: 0.875rem;
          color: @gray-800;
          border-left: 3px solid @success;
        }
      }

      .analysis-section {
        .analysis-label {
          font-size: 0.8125rem;
          color: @gray-600;
          font-weight: 500;
          display: flex;
          align-items: center;
          gap: 0.25rem;

          &:before {
            content: "";
            display: inline-block;
            width: 1rem;
            height: 1rem;
            background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%233B82F6'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z'/%3E%3C/svg%3E") no-repeat center;
            opacity: 0.8;
          }
        }

        .analysis-content {
          display: block;
          margin-top: 0.25rem;
          padding: 0.75rem;
          background: white;
          border-radius: @radius-md;
          font-size: 0.875rem;
          color: @gray-800;
          line-height: 1.6;
        }
      }

      .ai-tag {
        margin-top: 0.75rem;
        display: inline-flex;
        align-items: center;
        gap: 0.375rem;
        padding: 0.25rem 0.75rem;
        background: fade(@primary, 8%);
        color: @primary;
        border-radius: @radius-full;
        font-size: 0.75rem;
        font-weight: 500;

        i {
          font-size: 0.7rem;
        }
      }
    }
  }

  /* 批量操作按钮 */
  .batch-actions {
    display: flex;
    gap: 0.75rem;
    margin-top: 1.5rem;
    justify-content: flex-end;

    .batch-btn {
      padding: 0.625rem 1.25rem;
      border-radius: @radius-md;
      font-size: 0.8125rem;
      font-weight: 500;
      cursor: pointer;
      transition: all 0.2s ease;
      display: flex;
      align-items: center;
      gap: 0.5rem;
      border: none;
      box-shadow: @shadow-sm;

      &:hover {
        transform: translateY(-1px);
        box-shadow: @shadow-md;
      }

      i {
        font-size: 0.8rem;
      }

      &:first-child {
        background: @success;
        color: white;

        &:hover {
          background: darken(@success, 5%);
        }
      }

      &:nth-child(2) {
        background: @danger;
        color: white;

        &:hover {
          background: darken(@danger, 5%);
        }
      }

      &:last-child {
        background: @primary;
        color: white;

        &:hover {
          background: darken(@primary, 5%);
        }
      }
    }
  }
}

/* 空状态样式 */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 2rem;
  height: 100%;
  color: @gray-500;
  animation: fadeIn 0.3s ease-out;

  .empty-illustration {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: rgba(@primary, 0.1);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 1rem;

    i {
      font-size: 2rem;
      color: @primary;
    }
  }

  h4 {
    margin: 0.5rem 0;
    color: @gray-700;
    font-size: 1.125rem;
  }

  p {
    margin: 0;
    font-size: 0.875rem;
    max-width: 300px;
  }

  .btn-tutorial {
    margin-top: 1.5rem;
    background: rgba(@primary, 0.1);
    color: @primary;
    border: none;
    padding: 0.5rem 1rem;
    border-radius: @radius-md;
    font-size: 0.875rem;
    cursor: pointer;
    transition: @transition;
    display: flex;
    align-items: center;
    gap: 0.5rem;

    &:hover {
      background: rgba(@primary, 0.2);
      transform: translateY(-1px);
    }

    i {
      font-size: 0.8rem;
    }
  }
}

// 响应式调整
@media (max-width: 1024px) {
  .ai-generator-container {
    width: 95%;
    height: 90vh;
  }

  .left-panel {
    width: 320px;
  }

  .config-grid {
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  }

  .bank-card {
    height: 625px;
  }
}

@media (max-width: 768px) {
  .bank-card {
    height: 520px;
  }

  .ai-generator-container {
    width: 100%;
    height: 100vh;
    border-radius: 0;
  }

  .ai-generator-content {
    flex-direction: column;
  }

  .left-panel {
    width: 100%;
    border-right: none;
    border-bottom: 1px solid @gray-200;
    max-height: 40vh;
  }

  .result-panel {
    height: 60vh;
  }

  .config-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  }

  .type-config-grid {
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  }
}

@media (max-width: 480px) {
  .ai-generator-header {
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.75rem;

    .header-left {
      width: 100%;
      justify-content: space-between;
    }

    .header-actions {
      width: 100%;
      justify-content: flex-end;
    }
  }

  .config-grid {
    grid-template-columns: 1fr;
  }

  .type-config-grid {
    grid-template-columns: 1fr 1fr;
  }

  .batch-actions {
    flex-direction: column;
    gap: 0.5rem;

    .batch-btn {
      width: 100%;
      justify-content: center;
    }
  }

  .bank-card {
    height: 550px;
  }
}

// 工具类
.fade-in {
  animation: fadeIn 0.3s ease-out;
}

.fade-in-up {
  animation: fadeInUp 0.3s ease-out;
}

.shadow-transition {
  transition: box-shadow 0.3s ease;
}

// 加载状态
.loading-spinner {
  width: 24px;
  height: 24px;
  border: 3px solid rgba(@primary, 0.2);
  border-radius: 50%;
  border-top-color: @primary;
  animation: spin 1s linear infinite;
  display: inline-block;
}

.glow-effect {
  animation: glow 1.5s infinite;
}

// 关键词标签样式
.keyword-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.75rem;
  min-height: 32px;

  .keyword-tag {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.375rem 0.75rem;
    background: rgba(@primary, 0.1);
    color: @primary;
    border-radius: @radius-full;
    font-size: 0.8125rem;
    cursor: pointer;
    transition: all 0.3s ease;
    border: 1px solid rgba(@primary, 0.2);
    animation: tagEnter 0.3s ease-out;

    &:hover {
      background: rgba(@primary, 0.2);
      transform: translateY(-1px);
      box-shadow: @shadow-sm;

      i {
        color: @danger;
      }
    }

    i {
      font-size: 0.7rem;
      color: @primary;
      transition: color 0.2s ease;
    }

    &.tag-highlight {
      animation: tagHighlight 1s ease-out;
    }
  }
}

// 标签动画
@keyframes tagEnter {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.8);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes tagHighlight {
  0% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(@primary, 0.4);
  }
  50% {
    transform: scale(1.1);
    box-shadow: 0 0 0 10px rgba(@primary, 0);
  }
  100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(@primary, 0);
  }
}

// 标签过渡动画
.tag-fade-enter-active, .tag-fade-leave-active {
  transition: all 0.3s ease;
}

.tag-fade-enter, .tag-fade-leave-to {
  opacity: 0;
  transform: translateY(10px) scale(0.8);
}

.tag-fade-move {
  transition: transform 0.3s ease;
}

.recommendation-card.active {
  border-color: @primary !important;
  box-shadow: 0 0 0 2px fade(@primary, 20%);
  background: rgba(@primary, 0.05);
}

.option-item {
  position: relative;
}
.option-item.correct {
  background: #e6f7ff;
  border: 1.5px solid #4361EE;
  border-radius: 6px;
  color: #1d3557;
  position: relative;
}
.option-item.correct .correct-mark-after {
  display: inline-flex;
  align-items: center;
  background-color: rgba(67, 97, 238, 0.15);
  color: #4361EE;
  padding: 0.25rem 0.5rem;
  border-radius: 20px;
  font-size: 0.75rem;
  font-weight: 500;
  margin-left: 0.5rem;
  
  i {
    margin-right: 0.25rem;
  }
}
.question-index {
  font-size: 1.1rem;
  font-weight: bold;
  color: @primary;
  margin-right: 0.7rem;
}

// 新增分析中动画
.analyzing-recommendations {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 2rem;
  background: rgba(@primary, 0.1);
  border-radius: @radius-lg;
  margin-bottom: 1rem;

  .ai-loading-animation {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;

    .ai-brain {
      width: 60px;
      height: 60px;
      border-radius: 50%;
      background: linear-gradient(135deg, @primary, @secondary);
      color: white;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 1.5rem;
      box-shadow: @shadow-md;
      position: relative;

      &::after {
        content: '';
        position: absolute;
        top: -5px;
        left: -5px;
        right: -5px;
        bottom: -5px;
        border-radius: 50%;
        border: 2px solid rgba(@primary, 0.3);
        animation: pulse 2s infinite;
      }

      .brain-lobe {
        width: 10px;
        height: 10px;
        border-radius: 50%;
        background: linear-gradient(135deg, @primary, @secondary);
        position: absolute;
        animation: float 3s ease-in-out infinite;

        &.left {
          top: 10px;
          left: 10px;
        }
        &.right {
          top: 10px;
          right: 10px;
        }
        &.center {
          top: 30px;
          left: 0;
          right: 0;
        }
      }
    }

    .neural-connections {
      display: flex;
      justify-content: space-between;
      width: 100%;

      .connection {
        width: 10px;
        height: 10px;
        border-radius: 50%;
        background: linear-gradient(135deg, @primary, @secondary);
        animation: glow 1.5s infinite;
        animation-delay: var(--delay);
        animation-duration: var(--duration);
      }
    }

    .loading-text {
      font-size: 0.875rem;
      color: @gray-700;
      text-align: center;

      .text {
        font-weight: 500;
      }

      .dots {
        display: inline-flex;
        gap: 0.25rem;

        .dot {
          width: 4px;
          height: 4px;
          border-radius: 50%;
          background: @gray-700;
          animation: blink 1s infinite;
          animation-delay: var(--delay);
        }
      }
    }
  }
}

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

@keyframes pulse {
  0% { transform: scale(1); opacity: 1; }
  70% { transform: scale(1.1); opacity: 0.7; }
  100% { transform: scale(1.2); opacity: 0; }
}

@keyframes glow {
  0% { opacity: 0.3; transform: scale(0.8); }
  50% { opacity: 1; transform: scale(1.2); }
  100% { opacity: 0.3; transform: scale(0.8); }
}

@keyframes float {
  0% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
  100% { transform: translateY(0); }
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

// 空状态提示
.empty-recommendations {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 2rem;
  height: 150px;
  border-radius: @radius-lg;
  background: rgba(@primary, 0.05);
  color: @gray-500;
  animation: fadeIn 0.3s ease-out;
  margin-bottom: 1rem;
  border: 1px dashed rgba(@primary, 0.2);

  i {
    font-size: 2rem;
    margin-bottom: 1rem;
    color: @primary;
    opacity: 0.5;
  }

  p {
    font-size: 0.875rem;
    max-width: 300px;
    margin: 0;
  }
}

// 新增: 关键词建议刷新动画
.suggestions-refresh-enter-active,
.suggestions-refresh-leave-active {
  transition: all 0.5s cubic-bezier(0.19, 1, 0.22, 1);
}
.suggestions-refresh-enter-from {
  opacity: 0;
  transform: translateY(15px) scale(0.8);
}
.suggestions-refresh-leave-to {
  opacity: 0;
  transform: translateY(-15px) scale(0.8);
}
.suggestions-refresh-move {
  transition: transform 0.5s cubic-bezier(0.19, 1, 0.22, 1);
}

// 新增：现代通知动画
.notification-animated {
  animation: slideInRight 0.5s cubic-bezier(0.25, 1, 0.5, 1) forwards, 
             glow 2s ease-in-out 0.5s;
}

@keyframes slideInRight {
  from { transform: translateX(100%); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}

@keyframes glow {
  0% { box-shadow: 0 0 0 0 rgba(@primary, 0.2); }
  50% { box-shadow: 0 0 20px 5px rgba(@primary, 0.4); }
  100% { box-shadow: 0 0 0 0 rgba(@primary, 0.2); }
}

// 智能中心动画 - 给"AI建议关键词"标题添加智能动效
.suggestion-header {
  span {
    position: relative;
    
    &::after {
      content: '';
      position: absolute;
      bottom: -3px;
      left: 0;
      width: 0;
      height: 2px;
      background: @info;
      transition: width 0.5s cubic-bezier(0.19, 1, 0.22, 1);
    }
  }
  
  &:hover span::after {
    width: 100%;
  }
  
  // 刷新按钮动画加强
  .btn-refresh.refreshing {
    background: rgba(@info, 0.15);
    box-shadow: 0 0 0 2px rgba(@info, 0.2);
    
    i {
      animation: spin 0.8s cubic-bezier(0.5, 0.1, 0.5, 0.9) infinite;
    }
  }
}

// CSS样式更新
.keyword-highlight {
  font-weight: 600;
  color: @primary;
  background: rgba(@primary, 0.1);
  padding: 2px 6px;
  border-radius: 4px;
  display: inline-block;
  position: relative;
  overflow: hidden;
  
  &::after {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, 
                rgba(255,255,255,0) 0%,
                rgba(255,255,255,0.8) 50%,
                rgba(255,255,255,0) 100%);
    animation: shimmerEffect 1.5s ease-in-out;
  }
}

@keyframes shimmerEffect {
  0% { left: -100%; }
  100% { left: 100%; }
}

.quota-indicator {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0.75rem;
  border-radius: @radius-full;
  font-size: 0.75rem;
  font-weight: 500;
  background: rgba(@gray-500, 0.1);
  color: @gray-600;
  margin-left: auto;
  
  i {
    font-size: 0.8rem;
  }
  
  &.quota-warning {
    background: rgba(@warning, 0.15);
    color: @warning;
    animation: pulse 1s infinite alternate;
  }
}

.max-count {
  color: @gray-600;
  font-weight: 500;
}

// 修改卡片底部样式以适应内容高度
.card-footer {
  display: flex;
  flex-wrap: wrap; /* 允许内容换行 */
  justify-content: space-between;
  align-items: center;
  padding: 0.75rem 1rem;
  border-top: 1px solid @gray-200;
  background: @gray-50;
  min-height: 40px; /* 最小高度 */
  height: auto; /* 自动高度适应内容 */
  gap: 0.75rem;
  
  .footer-info {
    display: flex;
    flex-wrap: wrap; /* 允许在空间不足时换行 */
    gap: 1rem;
    color: @gray-600;
    font-size: 0.8125rem;
    
    .info-item {
      display: flex;
      align-items: center;
      gap: 0.5rem;
      white-space: normal; /* 允许文本换行 */
      
      i {
        color: @primary;
        flex-shrink: 0; /* 图标不缩小 */
      }
    }
  }
  
  .footer-actions {
    display: flex;
    gap: 0.75rem;
    
    @media (max-width: 576px) {
      width: 100%;
      justify-content: space-between;
      margin-top: 0.5rem;
    }
    
    button {
      padding: 0.375rem 0.75rem;
      border-radius: @radius-md;
      font-size: 0.8125rem;
      font-weight: 500;
      border: none;
      cursor: pointer;
      transition: @transition;
      display: flex;
      align-items: center;
      gap: 0.5rem;
      
      &.btn-analyze {
        background: rgba(@primary, 0.1);
        color: @primary;
        
        &:hover:not(:disabled) {
          background: rgba(@primary, 0.2);
          transform: translateY(-1px);
        }
        
        &:disabled {
          opacity: 0.7;
          cursor: not-allowed;
        }
      }
      
      &.btn-start {
        background: @primary;
        color: white;
        
        &:hover {
          background: darken(@primary, 5%);
          transform: translateY(-1px);
        }
      }
    }
  }
  
  /* 响应式布局支持 */
  @media (max-width: 576px) {
    flex-direction: column;
    align-items: flex-start;
    
    .footer-info {
      margin-bottom: 0.5rem;
    }
  }
}

.generation-hint {
  background: rgba(@warning, 0.1);
  color: @warning;
  padding: 0.5rem 1rem;
  border-radius: @radius-md;
  font-size: 0.875rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-right: auto;
  border-left: 3px solid @warning;
  
  i {
    font-size: 1rem;
  }
  
  @media (max-width: 768px) {
    width: 100%;
    margin-bottom: 0.5rem;
    font-size: 0.8125rem;
    padding: 0.375rem 0.75rem;
  }
}

.correct-mark-after {
  display: inline-flex;
  align-items: center;
  background-color: rgba(67, 97, 238, 0.15);
  color: #4361EE;
  padding: 0.25rem 0.5rem;
  border-radius: 20px;
  font-size: 0.75rem;
  font-weight: 500;
  margin-left: 0.5rem;
  
  i {
    margin-right: 0.25rem;
  }
}

.regenerating-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.9);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  z-index: 1000;
  border-radius: @radius-xl;
  backdrop-filter: blur(2px);

  .regenerating-spinner {
    display: flex;
    flex-direction: column;
    align-items: center;
    
    .spinner-border {
      width: 40px;
      height: 40px;
      border: 3px solid @primary;
      border-radius: 50%;
      border-top-color: transparent;
      animation: spin 1s linear infinite;
    }

    .regenerating-text {
      margin-top: 1rem;
      font-size: 0.9rem;
      font-weight: 500;
      color: @gray-700;
      text-align: center;
    }
  }
}

.loading {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
</style>